费用流 建图时额外添加一个点A(左->A:(1,0) A->T:(inf,0))来保证满流 边少点多较快 边多的情况下表现很差
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<ctime> 5 #include<iostream> 6 #include<algorithm> 7 #include<queue> 8 #include<set> 9 #define inf (1ll<<(61ll)) 10 #define l(a) ((a)<<1) 11 #define r(a) ((a)<<1|1) 12 #define b(a) (1<<(a)) 13 #define rep(i,a,b) for(int i=a;i<=(b);i++) 14 #define clr(a) memset(a,0,sizeof(a)) 15 typedef long long ll; 16 using namespace std; 17 int readint(){ 18 int t=0,f=1;char c=getchar(); 19 while(!isdigit(c)){ 20 if(c=='-') f=-1; 21 c=getchar(); 22 } 23 while(isdigit(c)){ 24 t=(t<<3)+(t<<1)+c-'0'; 25 c=getchar(); 26 } 27 return t*f; 28 } 29 const int maxn=1009,maxe=400009; 30 int n,m,en,S,A,T; 31 ll d[maxn]; 32 ll ans; 33 struct edge{ 34 ll v,w,c; 35 edge*next,*r; 36 }E[maxe],*pt=E,*fir[maxn],*cur[maxn],*rev[maxn]; 37 void add(int u,int v,int w,int c){ 38 pt->v=v;pt->w=w;pt->c=c; 39 pt->next=fir[u];fir[u]=pt++; 40 } 41 void addedge(int u,int v,int w,int c){ 42 add(u,v,w,c);add(v,u,0,-c); 43 fir[u]->r=fir[v];fir[v]->r=fir[u]; 44 } 45 bool p[maxn]; 46 ll spfa(){ 47 queue<int>Q;clr(p); 48 rep(i,S,T) d[i]=-inf; 49 Q.push(S);p[S]=1;d[S]=0; 50 while(!Q.empty()){ 51 int x=Q.front();Q.pop();p[x]=0; 52 for(edge*e=fir[x];e;e=e->next) if(e->w){ 53 if(d[e->v]<d[x]+e->c){ 54 d[e->v]=d[x]+e->c; 55 rev[e->v]=e; 56 if(!p[e->v]){ 57 Q.push(e->v);p[e->v]=1; 58 } 59 } 60 } 61 } 62 if(d[T]==-inf) return 0; 63 for(edge*e=rev[T];e;e=rev[e->r->v]){ 64 e->w-=1;e->r->w+=1; 65 } 66 return d[T]; 67 } 68 void Cal(){ 69 ll t; 70 while(t=spfa()) ans+=t; 71 } 72 int main(){ 73 //freopen("#input.txt","r",stdin); 74 //freopen("#output.txt","w",stdout); 75 n=readint();m=readint();en=readint();S=0;A=n+m+1;T=A+1; 76 rep(i,1,en){ 77 int U=readint(),V=readint(),C=readint(); 78 addedge(U,n+V,1,C); 79 } 80 rep(i,1,n) addedge(S,i,1,0); 81 rep(i,1,m) addedge(n+i,T,1,0); 82 rep(i,1,n) addedge(i,A,1,0);addedge(A,T,1000009,0); 83 Cal(); 84 cout<<ans<<endl; 85 rep(i,1,n){ 86 int f=0; 87 for(edge*e=fir[i];e;e=e->next){ 88 if(!e->w&&e->v!=A&&e->v!=S) f=e->v-n; 89 } 90 printf("%d",f);putchar(i==n?'\n':' '); 91 } 92 //fclose(stdin); 93 //fclose(stdout); 94 return 0; 95 }