【UOJ 80】 二分图最大权匹配
【分析】
之前打的那种KM会TLE。。。
why??明明说n^3的啊?
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define Maxn 410 9 #define Maxm 160010 10 // #define INF 0x7fffffff 11 #define LL long long 12 const LL INF=1LL<<62; 13 14 LL mymin(LL x,LL y) {return x<y?x:y;} 15 LL mymax(LL x,LL y) {return x>y?x:y;} 16 17 int N; 18 19 int n,m; 20 int match[Maxn],op[Maxn]; 21 LL eg[Maxn][Maxn],lx[Maxn],ly[Maxn],slack[Maxn]; 22 int visx[Maxn],visy[Maxn],pre[Maxn]; 23 24 void mh(int y) 25 { 26 for(int x,z;y>0;y=z) 27 { 28 x=pre[y];z=op[x]; 29 op[x]=y;match[y]=x; 30 } 31 } 32 33 int nt; 34 void ffind(int st) 35 { 36 for(int i=1;i<=N;i++) slack[i]=INF; 37 queue<int> q;nt++; 38 q.push(st);visx[st]=nt; 39 while (1) 40 { 41 while(!q.empty()) 42 { 43 int x=q.front();q.pop(); 44 for(int y=1;y<=N;y++) 45 if(visy[y]!=nt) 46 { 47 if(lx[x]+ly[y]==eg[x][y]) 48 { 49 pre[y]=x; 50 if(!match[y]) {mh(y);return;} 51 q.push(match[y]); 52 visx[match[y]]=nt;visy[y]=nt; 53 } 54 else if(slack[y]>lx[x]+ly[y]-eg[x][y]) 55 slack[y]=lx[x]+ly[y]-eg[x][y],pre[y]=x; 56 } 57 } 58 LL delta=INF; 59 for(int y=1;y<=N;y++) if(visy[y]!=nt) delta=mymin(delta,slack[y]); 60 for(int i=1;i<=N;i++) 61 { 62 if(visx[i]==nt) lx[i]-=delta; 63 if(visy[i]==nt) ly[i]+=delta; 64 else slack[i]-=delta; 65 } 66 for(int i=1;i<=N;i++) if(visy[i]!=nt&&slack[i]==0) 67 { 68 if(!match[i]) {mh(i);return;} 69 q.push(match[i]); 70 visx[match[i]]=nt;visy[i]=nt; 71 } 72 } 73 } 74 75 76 LL KM() 77 { 78 memset(visx,0,sizeof(visx)); 79 memset(visy,0,sizeof(visy)); 80 for (int i=1;i<=N;i++) lx[i]=ly[i]=0,op[i]=match[i]=0; 81 for (int i=1;i<=N;i++) 82 for (int j=1;j<=N;j++) 83 lx[i]=mymax(lx[i],eg[i][j]); 84 for (int i=1;i<=N;i++) ffind(i); 85 } 86 87 void output() 88 { 89 LL ans=0; 90 for(int i=1;i<=N;i++) ans+=lx[i]+ly[i]; 91 printf("%lld\n",ans); 92 for(int i=1;i<=n;i++) if(eg[i][op[i]]!=0) printf("%d ",op[i]); 93 else printf("0 ");printf("\n"); 94 } 95 96 void init() 97 { 98 int l; 99 memset(eg,0,sizeof(eg)); 100 scanf("%d%d%d",&n,&m,&l); 101 for(int i=1;i<=l;i++) 102 { 103 int x,y; 104 LL c; 105 scanf("%d%d%lld",&x,&y,&c); 106 eg[x][y]=mymax(eg[x][y],c); 107 } 108 N=mymax(n,m); 109 } 110 111 int main() 112 { 113 init(); 114 KM(); 115 output(); 116 return 0; 117 }