中文題意不描述。node
連接:http://wikioi.com/problem/1028/ios
這題一開始很裸的最大權二分匹配。可是原來沒有接觸過,KM的這個最大權不大會。而後一開始覺得用最大費用最大流直接就能搞,後來知道單純的費用流解決的是二分最佳匹配,而不是最大權,QCMM而後看了一下這個http://hi.baidu.com/lerroy312/item/42e718ba58a1f8df85dd795fide
結果改了以後不對,不知道爲何最後用的最小費用,對邊的權值取負值,結果取負值才過。。。不解。。。spa
1 #include <iostream> 2 #include <queue> 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 #include <vector> 7 using namespace std; 8 const int maxn = 350; 9 const int inf = 10000000; 10 struct node 11 { 12 int u,v,cap,flow,cost,next; 13 }edges[100050]; 14 int head[maxn],cnt; 15 void init(int n) 16 { 17 int i; 18 for(i = 0;i <= n;i++) 19 head[i] = -1; 20 cnt = 0; 21 22 return ; 23 } 24 void addedge(int u,int v,int cap,int cost) 25 { 26 edges[cnt].u = u; 27 edges[cnt].v = v; 28 edges[cnt].cap = cap; 29 edges[cnt].flow = 0; 30 edges[cnt].cost = cost; 31 edges[cnt].next = head[u]; 32 head[u] = cnt; 33 cnt++; 34 edges[cnt].u = v; 35 edges[cnt].v = u; 36 edges[cnt].cap = 0; 37 edges[cnt].flow = 0; 38 edges[cnt].cost = -cost; 39 edges[cnt].next = head[v]; 40 head[v] = cnt; 41 cnt++; 42 } 43 int vis[maxn],a[maxn],pre[maxn],dis[maxn]; 44 int spfa(int s,int t,int n,int &flow,int &cost) 45 { 46 int i; 47 queue<int> q; 48 for(i = 0;i <= n ;i++) 49 dis[i] = inf,vis[i] = 0; 50 51 dis[s] = 0; 52 pre[s] = 0; 53 vis[s] = 1; 54 a[s] = inf; 55 56 int u,v; 57 q.push(s); 58 59 while(!q.empty()) 60 { 61 u = q.front(); 62 q.pop(); 63 vis[u] = 0; 64 65 for(i = head[u];i != -1;i = edges[i].next) 66 { 67 struct node & e = edges[i]; 68 69 v = e.v; 70 if(e.cap > e.flow &&dis[v] > dis[u]+e.cost) 71 { 72 dis[v] = dis[u]+e.cost; 73 a[v] = min(a[u],e.cap-e.flow); 74 pre[v] = i; 75 if(!vis[v]) 76 { 77 vis[v] = 1; 78 q.push(v); 79 } 80 } 81 } 82 } 83 84 if(dis[t] >= inf) 85 return 0; 86 flow+= a[t]; 87 cost += dis[t]*a[t]; 88 u = t; 89 while(u != s) 90 { 91 edges[pre[u]].flow += a[t]; 92 edges[pre[u]^1].flow -= a[t]; 93 u = edges[pre[u]].u; 94 } 95 return 1; 96 } 97 int mcmf(int s,int t, int n) 98 { 99 int cost = 0,flow = 0; 100 while(spfa(s,t,n,flow,cost)); 101 102 return cost; 103 } 104 int main() 105 { 106 int n,m; 107 scanf("%d %d",&n,&m); 108 109 int i,j; 110 init(n+m+4); 111 for(i =1;i <= n;i++) 112 { 113 addedge(0,i,1,0); 114 for(j = 1;j <= m;j++) 115 { 116 int w; 117 scanf("%d",&w); 118 addedge(i,j+n,1,-w); 119 } 120 addedge(i,m+n+1,1,0); 121 } 122 addedge(n+m+1,m+n+2,n,0); 123 for(j = 1;j <= m;j++) 124 addedge(j+n,m+n+2,1,0); 125 cout<<-mcmf(0,m+n+2,m+n+3)<<endl; 126 return 0; 127 }
額,最近跟scu-frog神請教了下這個問題,scu-frog神看了下代碼,說你的最長路的初始化有問題,有負權邊爲何賦值-1.code
而後默默對本身說了一句sb。。。默默改了交了一下,ac= =。blog
1 #include <iostream> 2 #include <queue> 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 #include <vector> 7 using namespace std; 8 const int maxn = 350; 9 const int inf = 10000000; 10 struct node 11 { 12 int u,v,cap,flow,cost,next; 13 }edges[100050]; 14 int head[maxn],cnt; 15 void init(int n) 16 { 17 int i; 18 for(i = 0;i <= n;i++) 19 head[i] = -1; 20 cnt = 0; 21 22 return ; 23 } 24 void addedge(int u,int v,int cap,int cost) 25 { 26 edges[cnt].u = u; 27 edges[cnt].v = v; 28 edges[cnt].cap = cap; 29 edges[cnt].flow = 0; 30 edges[cnt].cost = cost; 31 edges[cnt].next = head[u]; 32 head[u] = cnt; 33 cnt++; 34 edges[cnt].u = v; 35 edges[cnt].v = u; 36 edges[cnt].cap = 0; 37 edges[cnt].flow = 0; 38 edges[cnt].cost = -cost; 39 edges[cnt].next = head[v]; 40 head[v] = cnt; 41 cnt++; 42 } 43 int vis[maxn],a[maxn],pre[maxn],dis[maxn]; 44 int spfa(int s,int t,int n,int &flow,int &cost) 45 { 46 int i; 47 queue<int> q; 48 for(i = 0;i <= n ;i++) 49 dis[i] = -inf,vis[i] = 0; 50 51 dis[s] = 0; 52 pre[s] = 0; 53 vis[s] = 1; 54 a[s] = inf; 55 56 int u,v; 57 q.push(s); 58 59 while(!q.empty()) 60 { 61 u = q.front(); 62 q.pop(); 63 vis[u] = 0; 64 65 for(i = head[u];i != -1;i = edges[i].next) 66 { 67 struct node & e = edges[i]; 68 69 v = e.v; 70 if(e.cap > e.flow &&dis[v] < dis[u]+e.cost) 71 { 72 dis[v] = dis[u]+e.cost; 73 a[v] = min(a[u],e.cap-e.flow); 74 pre[v] = i; 75 if(!vis[v]) 76 { 77 vis[v] = 1; 78 q.push(v); 79 } 80 } 81 } 82 } 83 84 if(dis[t] <= -inf) 85 return 0; 86 flow+= a[t]; 87 cost += dis[t]*a[t]; 88 u = t; 89 while(u != s) 90 { 91 edges[pre[u]].flow += a[t]; 92 edges[pre[u]^1].flow -= a[t]; 93 u = edges[pre[u]].u; 94 } 95 return 1; 96 } 97 int mcmf(int s,int t, int n) 98 { 99 int cost = 0,flow = 0; 100 while(spfa(s,t,n,flow,cost)); 101 102 return cost; 103 } 104 int main() 105 { 106 int n,m; 107 scanf("%d %d",&n,&m); 108 109 int i,j; 110 init(n+m+4); 111 for(i =1;i <= n;i++) 112 { 113 addedge(0,i,1,0); 114 for(j = 1;j <= m;j++) 115 { 116 int w; 117 scanf("%d",&w); 118 addedge(i,j+n,1,w); 119 } 120 addedge(i,m+n+1,1,0); 121 } 122 addedge(n+m+1,m+n+2,n,0); 123 for(j = 1;j <= m;j++) 124 addedge(j+n,m+n+2,1,0); 125 cout<<mcmf(0,m+n+2,m+n+3)<<endl; 126 return 0; 127 }