(2016北京集训十四)【xsy1557】task

题解:

限制可以看成图状结构,每个任务的对物品数量的影响可以看成权值,只不过这个权值用一个五元组来表示。

那么题意要求的就是最大权闭合子图,网络流经典应用。

代码:

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 #include<queue>
  7 #define inf 100000000000000000
  8 using namespace std;
  9 typedef long long ll;
 10 struct edge{
 11     int v,next;
 12     ll w;
 13 }a[100001];
 14 int n,m,k,u,v,vs,vt,tot=1,dep[100001],anss[10],head[100001];
 15 ll ans=0,tmp,sum=0,cnt=0;
 16 char op[10];
 17 queue<int>q;
 18 void add(int u,int v,ll w){
 19     a[++tot].v=v;
 20     a[tot].w=w;
 21     a[tot].next=head[u];
 22     head[u]=tot;
 23 }
 24 bool bfs(){
 25     memset(dep,0,sizeof(dep));
 26     while(!q.empty())q.pop();
 27     q.push(vs);
 28     dep[vs]=1;
 29     while(!q.empty()){
 30         int u=q.front();
 31         q.pop();
 32         for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
 33             int v=a[tmp].v;
 34             if(!dep[v]&&a[tmp].w){
 35                 dep[v]=dep[u]+1;
 36                 if(v==vt)return true;
 37                 q.push(v);
 38             }
 39         }
 40     }
 41     return false;
 42 }
 43 ll dfs(int u,ll num){
 44     if(u==vt||!num)return num;
 45     ll ans=0;
 46     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
 47         int v=a[tmp].v;
 48         ll w=a[tmp].w;
 49         if(dep[v]==dep[u]+1&&w){
 50             ll f=dfs(v,min(num,w));
 51             if(f){
 52                 a[tmp].w-=f;
 53                 a[tmp^1].w+=f;
 54                 ans+=f;
 55                 num-=f;
 56                 if(!num)break;
 57             }
 58         }
 59     }
 60     if(num>0)dep[u]=-1;
 61     return ans;
 62 }
 63 int main(){
 64     memset(head,-1,sizeof(head));
 65     scanf("%d%d%d",&n,&m,&k);
 66     vs=n+1,vt=n+2;
 67     for(int i=1;i<=k;i++)ans=ans*2001+1000;
 68     for(int i=1;i<=n;i++){
 69         scanf("%s",op+1);
 70         tmp=0;
 71         for(int j=1;j<=k;j++){
 72             tmp*=2001;
 73             if(op[j]=='+')tmp++;
 74             if(op[j]=='-')tmp--;
 75         }
 76         if(tmp<0){
 77             add(vs,i,-tmp);
 78             add(i,vs,0);
 79         }else{
 80             sum+=tmp;
 81             add(i,vt,tmp);
 82             add(vt,i,0);
 83         }
 84     }
 85     for(int i=1;i<=m;i++){
 86         scanf("%d%d",&u,&v);
 87         add(v,u,inf);
 88         add(u,v,0);
 89     }
 90     while(bfs()){
 91         cnt+=dfs(vs,inf);
 92     }
 93     ans-=cnt-sum;
 94     for(int i=k;i;i--){
 95         anss[i]=ans%2001;
 96         ans/=2001;
 97     }
 98     for(int i=1;i<=k;i++)printf("%d ",anss[i]);
 99     return 0;
100 }

 

posted @ 2018-09-24 21:19  DCDCBigBig  阅读(164)  评论(0编辑  收藏  举报