codeforces gym 100357 J (网络流)

题目大意

  有n种物品,m种建筑,p个人。 n,m,p∈[1,20]

  每种建筑需要若干个若干种物品来建造。每个人打算建造一种建筑,拥有一些物品。

  主角需要通过交易来建造自己的建筑,交易的前提是对方用多余的物品来换取自己需要的物品。

  询问主角是否能建造成功自己的建筑,并给出方案。  

解题分析

  超级恶心的读入,而且有一组数据的给出方式里没有逗号,和样例所示不同= =

  根据py的性质很容易想到用网络流来做。将每种物品拆成x,y两份。

  若主角多了a物品b件,连一条S到物品a,x部流量为b的边。

  若主角少了a物品b件,连一条物品a,y部到T流量为b的边。

  若某人少了a物品b件,连一条物品a,x部流量为b到该人流量为b的边。

  若某人多了a物品b件,连一条该人到物品a,y部流量为b到该人流量为b的边。  模拟了一次交易的进行。

  再由每个物品的y部向每个物品的x部连一条流量为无穷大的边。  表示交易可以不停的进行。

  跑一遍网络流,如果是满流的话,说明可以成功。

  输出方案则再残量网络上进行一次dfs,将每一次的交易的情况依次输出。

参考程序

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define rep(i,x,y) for (int i=x;i<=y;i++)
  5 //#define DEBUG
  6 const int N=500;
  7 const int INF=2000000000;
  8 
  9 int n,m,p,sum,lt[N],cur[N],S,TT,T,dis[N];
 10 
 11 struct node{
 12     int u,v,f,nt;
 13 }eg[N*2];
 14 
 15 
 16 map <string,int> build_number;
 17 map <string,int> res_number;
 18 string res_name[N];
 19 string build_name[N];
 20 string people_name[N];
 21 string my_build;
 22 
 23 int build_need[N][N];
 24 int people_has[N][N];
 25 
 26 void add(int u,int v,int f)
 27 {
 28     #ifdef DEBUG
 29     cout<<u<<" "<<v<<" "<<f<<endl;
 30     #endif
 31     eg[++sum]=(node){u,v,f,lt[u]}; lt[u]=sum;
 32     eg[++sum]=(node){v,u,0,lt[v]}; lt[v]=sum;
 33 }
 34 
 35 bool bfs()
 36 {
 37     memset(dis,0,sizeof(dis));
 38     queue <int> Q;
 39     dis[S]=1; Q.push(S);
 40     while (!Q.empty())
 41     {
 42         int u=Q.front(); Q.pop();
 43         for (int i=lt[u];i;i=eg[i].nt)
 44         {
 45             int v=eg[i].v;
 46             if (eg[i].f && !dis[v])
 47             {
 48                 dis[v]=dis[u]+1;
 49                 Q.push(v);
 50             }
 51         }
 52     }
 53     return dis[T];
 54 }
 55 
 56 int dfs(int u,int flow)
 57 {
 58     if (u==T) return flow;
 59     int res=0,f;
 60     for (int &i=cur[u];i;i=eg[i].nt)
 61     {
 62         int v=eg[i].v;
 63         if (eg[i].f && dis[v]==dis[u]+1)
 64         {
 65             f=dfs(v,min(flow-res,eg[i].f));  
 66             res+=f;
 67             eg[i].f-=f; eg[i^1].f+=f;
 68             if (res==flow) break;
 69         }
 70     }
 71     return res;
 72 }
 73 
 74 int dinic()
 75 {
 76     int sum=0;
 77     while (bfs()) 
 78     {
 79         rep(i,S,T) cur[i]=lt[i];
 80         sum+=dfs(S,INF);
 81     }
 82     return sum;
 83 }
 84 
 85 void solve(int u,int fa)
 86 {
 87     //cout<<u<<" "<<fa<<endl;
 88     if (u==T) return;
 89     for (int i=lt[u];i;i=eg[i].nt)
 90         if (i%2==0 && eg[i^1].f)
 91         {
 92             int v=eg[i].v;
 93             int times=1;
 94             if (u==S) times=eg[i^1].f;
 95             rep(j,1,times)
 96             {
 97                 eg[i^1].f--;
 98                 if (u>=n+1 && u<=n+p)
 99                 {
100                     //cout<<u-n<<" "<<fa<<" "<<v-n-p<<" "<<v<<endl;
101                     cout<<"trade with "<<people_name[u-n]<<" "<<res_name[fa]<<" for "<<res_name[v-n-p]<<endl;
102                 }
103                 solve(v,u);
104             }
105             if (u!=S) break;
106         }
107 }
108 
109 int main()
110 {
111     freopen("trading.in","r",stdin);
112     #ifndef DEBUG
113     freopen("trading.out","w",stdout);
114     #endif
115     char ch;
116     cin.sync_with_stdio(0);
117     memset(lt,0,sizeof(lt)); sum=1;
118     cin>>p>>n>>m;    
119     S=0,TT=n*2+p+1,T=n*2+p+2;
120     int total=0;
121     rep(i,1,n) 
122     {
123         cin>>res_name[i];
124         res_number[res_name[i]]=i;
125     }
126 
127     rep(i,1,m)
128     {
129         cin>>build_name[i];
130         build_number[build_name[i]]=i;
131         string s;
132         cin>>s;
133         for (;;)
134         {
135             int x;
136             cin>>x>>s;
137             if (s[s.length()-1]==',')
138             {
139                 s.erase(s.end()-1);
140                 build_need[i][res_number[s]]=x;
141             }
142             else
143             {
144                 build_need[i][res_number[s]]=x;
145             }
146             cin.get(ch);
147             if (ch=='\n') break;
148         }
149     }
150 
151     string s; cin>>s>>s>>s;
152 
153 
154     if (s[s.length()-1]==',') s.erase(s.end()-1);
155     my_build=s;
156     cin.get(ch);
157     if (ch!='\n') 
158     {
159         string t; cin>>t;
160         for (;;)
161         {
162             int x; cin>>x>>t;
163             if (t[t.length()-1]==',')
164             {
165                 t.erase(t.end()-1);
166                 people_has[1][res_number[t]]=x;
167             }
168             else
169             {
170                 people_has[1][res_number[t]]=x;
171             }
172             cin.get(ch);
173             if (ch=='\n') break;
174         }
175     }
176 
177     rep(i,1,n) 
178     {
179         int y=people_has[1][i]-build_need[build_number[s]][i];
180         if (y>0) add(S,i,y);
181         if (y<0) {add(i+n+p,TT,-y); total+=-y;}
182     }
183 
184     add(TT,T,total);
185 
186     rep(i,2,p)
187     {
188         string s; cin>>people_name[i]>>s>>s; 
189         if (s[s.length()-1]==',') s.erase(s.end()-1);
190         cin.get(ch);
191         if (ch=='\n') continue;
192         string t; cin>>t;
193         for (;;)
194         {
195             int x; cin>>x>>t;
196             if (t[t.length()-1]==',')
197             {
198                 t.erase(t.end()-1);
199                 people_has[i][res_number[t]]=x;
200             }
201             else
202             {
203                 people_has[i][res_number[t]]=x;
204             }
205             cin.get(ch);
206             //cout<<(int)ch<<endl;
207             if (cin.fail()) break;
208             if (ch=='\n') break;
209         }
210         rep(j,1,n) 
211         {
212             //cout<<"\t"<<j<<" "<<people_has[i][j]<<" "<<build_need[build_number[s]][j]<<endl;
213             int y=people_has[i][j]-build_need[build_number[s]][j];
214             if (y>0) add(i+n,n+p+j,y);
215             if (y<0) add(j,i+n,-y);
216         }
217     }
218     rep(i,1,n) add(n+p+i,i,INF);
219 
220     int x=dinic();
221 
222     #ifdef DEBUG
223     cout<<x<<" "<<total<<endl;
224     #endif
225     if (x==total) {solve(S,0); cout<<"build "<<my_build<<endl;}
226     else cout<<"No way"<<endl;
227 }
View Code

 

posted @ 2017-04-30 23:45  rpSebastian  阅读(371)  评论(0编辑  收藏  举报