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
  • 相关阅读:
    Oracle数据库事务
    MSSQL数据库事务
    MSSQL公用方法查询最新ID
    UISwitch的用法总结开关用法
    iPhone和ipad键盘高度及键盘响应事件 摘
    ios 6 的 小改变
    instance method 'addMask' not found (return type defaults to 'id')
    关于tableView group样式 时设置 cell的width 宽度
    判断 iPhone 虚拟键盘是否打开的代码 (转)
    UITextField 控件详解 我见过的史上最牛x的
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/6790770.html
Copyright © 2011-2022 走看看