一个源点,一个汇点,明显是网络流的问题,但据说用网络流来求最小割,会超时。。囧,那出题的人是怎么想的。。。
用SW的算法来求最小割。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int MAXN=310; 7 const int inf=100000000; 8 int vis[MAXN],combine[MAXN],wan[MAXN]; 9 int map[MAXN][MAXN]; 10 int n,m,t; 11 int mincut,S,T; 12 13 void seacut(){ 14 int Max; int p; 15 S=T=-1; 16 memset(vis,0,sizeof(vis)); 17 memset(wan,0,sizeof(wan)); 18 for(int i=0;i<n;i++){ 19 Max=-inf; 20 for(int j=0;j<n;j++){ 21 if(!combine[j]&&!vis[j]&&wan[j]>Max){ 22 Max=wan[j]; p=j; 23 } 24 } 25 if(p==T) return; 26 S=T;T=p; 27 vis[T]=1; 28 for(int j=0;j<n;j++){ 29 if(!combine[j]&&!vis[j]){ 30 wan[j]+=map[T][j]; 31 } 32 } 33 } 34 } 35 36 void storewanger(){ 37 mincut=inf; 38 memset(combine,0,sizeof(combine)); 39 for(int i=0;i<n-1;i++){ 40 seacut(); 41 if(wan[T]<mincut) mincut=wan[T]; 42 if(mincut==0) return; 43 combine[T]=1; 44 for(int j=0;j<n;j++){ 45 if(!combine[j]){ 46 map[S][j]+=map[T][j]; 47 map[j][S]+=map[j][T]; 48 } 49 } 50 } 51 } 52 53 int main(){ 54 int u,v,w; 55 while(scanf("%d%d%d",&n,&m,&t)!=EOF){ 56 if(!n&&!m&&!t) break; 57 memset(map,0,sizeof(map)); 58 for(int i=0;i<m;i++){ 59 scanf("%d%d%d",&u,&v,&w); 60 u--; v--; 61 map[u][v]+=w; 62 map[v][u]+=w; 63 } 64 storewanger(); 65 printf("%d ",mincut); 66 } 67 return 0; 68 }