标签:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 5 #include<string> 6 #include<algorithm> 7 #include<set> 8 #include<map> 9 #include<vector> 10 #include<stack> 11 #include<queue> 12 #include<cmath> 13 14 #include<iostream> 15 using namespace std; 16 #define Del(a,b) memset(a,b,sizeof(a)) 17 const int inf = 0x7f7f7f7f; 18 const int N = 500+5; 19 struct Node 20 { 21 int from,to,cap,flow,cost; 22 Node(int f,int t,int c,int fl,int co){ 23 from = f , to = t, cap = c,flow = fl, cost = co; 24 } 25 }; 26 vector<Node> e; 27 vector<int> v[N]; 28 int vis[N],dis[N]; 29 int p[N],a[N]; //p保存father,a保存cap 30 void Clear(int x) 31 { 32 for(int i=0 ; i < N;i++) 33 v[i].clear(); 34 e.clear(); 35 } 36 void add_Node(int from,int to,int cap,int cost) 37 { 38 // e.push_back((Node){from,to,cap,0,cost}); 39 // e.push_back((Node){to,from,0,0,-cost}); 40 e.push_back(Node(from,to,cap,0,cost)); 41 e.push_back(Node(to,from,0,0,-cost)); 42 int len = e.size()-1; 43 v[to].push_back(len); 44 v[from].push_back(len-1); 45 } 46 bool BellmanFord(int s,int t,int& flow,int& cost) 47 { 48 Del(dis,inf); 49 Del(vis,0); 50 dis[s] = 0; 51 vis[s] = 1; 52 p[s] = 0; 53 a[s] = inf; 54 queue<int> q; 55 q.push(s); 56 while(!q.empty()) 57 { 58 int u = q.front(); 59 q.pop(); 60 vis[u] = 0; 61 for(int i=0; i<v[u].size(); i++) 62 { 63 Node& g = e[v[u][i]]; 64 if(g.cap>g.flow && dis[g.to] > dis[u]+g.cost) 65 { 66 dis[g.to] = dis[u] + g.cost; 67 p[g.to] = v[u][i]; //保存前驱 68 a[g.to] = min(a[u],g.cap-g.flow); 69 if(!vis[g.to]) 70 { 71 q.push(g.to); 72 vis[g.to]=1; 73 } 74 75 } 76 } 77 } 78 if(dis[t] == inf) 79 return false; 80 flow += a[t]; 81 cost += dis[t]*a[t]; 82 int u = t; 83 while(u!=s) 84 { 85 e[p[u]].flow += a[t]; 86 e[p[u]^1].flow -= a[t]; 87 u = e[p[u]].from; 88 } 89 return true; 90 } 91 void Min_Cost(int s,int t) 92 { 93 int flow=0,cost = 0; 94 while(BellmanFord(s,t,flow,cost)); 95 printf("%d ",flow); 96 printf("%d\n",flow*2 - cost); 97 //return cost; 98 } 99 100 /* 101 p a e v dis ,vis N have been used; 102 */ 103 int n,m,source,sink,len,belong[600],sex[600],g[600][600],tmp; 104 char str[600]; 105 void getMap(){ 106 107 memset(belong,0,sizeof(belong)); 108 memset(sex,0,sizeof(sex)); 109 memset(g,0,sizeof(g)); 110 111 Clear(n); 112 scanf("%d",&n); 113 source = 0 , sink = n+1; 114 scanf("%s",str); 115 for(int i = 0 ; str[i] ; i ++) 116 if(str[i] == ‘1‘) 117 belong[i+1] = 1; 118 119 // for(int i=0;str[i];i++) belong[i+1]=str[i]-‘0‘; 120 scanf("%s",str); 121 for(int i = 0 ; str[i] ; i ++) 122 if(str[i] == ‘1‘) 123 sex[i+1] = 1; 124 // for(int i=0;str[i];i++) sex[i+1]=str[i]-‘0‘; 125 126 for(int i = 1 ; i <= n ; i ++){ 127 scanf("%d",&m); 128 for(int j = 1 ; j <= m ; j ++){ 129 scanf("%d",&tmp); 130 g[i][tmp] = g[tmp][i] = 1; 131 } 132 } 133 //连接 source 与 group1 void add_Node(int from,int to,int cap,int cost) 134 for(int i = 1 ; i <= n ; i ++){ 135 if(belong[i] == 0){ 136 add_Node(source,i,1,0); 137 }else{ 138 add_Node(i,sink,1,0); 139 } 140 } 141 142 for(int i = 1 ; i <= n ; i ++){ 143 if(belong[i] == 1) continue; 144 for(int j = 1 ; j <= n ; j ++){ 145 if(belong[j] == 0) continue; 146 if(i == j) continue; 147 if(g[i][j] == 1) continue; 148 add_Node(i,j,1,sex[i]+sex[j]); 149 } 150 } 151 } 152 153 int main(){ 154 int T; 155 scanf("%d",&T); 156 while(T--){ 157 getMap(); 158 Min_Cost(source,sink); 159 for(int i = 0 ; i < e.size(); i = i+2) // 跳过反向边 160 { 161 if(e[i].from == 0) continue; 162 if(e[i].to == n+1) continue; 163 if(e[i].flow == 0) continue; 164 printf("%d %d\n",e[i].from,e[i].to); 165 } 166 } 167 return 0; 168 }
zoj 3933 Team Formation(最小费用流裸题)
标签:
原文地址:http://www.cnblogs.com/zstu-jack/p/5398878.html