码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 3933 Team Formation(最小费用流裸题)

时间:2016-04-16 18:42:46      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:

 

技术分享

 

  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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!