zoukankan      html  css  js  c++  java
  • 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=='
    ') 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!='
    ') 
    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=='
    ') 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=='
    ') 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=='
    ') break;
    209         }
    210         rep(j,1,n) 
    211         {
    212             //cout<<"	"<<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
  • 相关阅读:
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Path Sum
    Symmetric Tree
    Solve Tree Problems Recursively
    632. Smallest Range(priority_queue)
    609. Find Duplicate File in System
    poj3159最短路spfa+邻接表
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/6790770.html
Copyright © 2011-2022 走看看