省选模拟赛 project

solution:
最小割问题。
建如下边:
(S,i,Ai)代表选用A语言编写第i个项目;
(i,T,Bi)代表选用A语言编写第i个项目;
其后注意要反向连边
(i,j,D)代表选用B语言编写第i个项目,选用A语言编写第j个项目;
(j,i,C)代表选用A语言编写第i个项目,选用B语言编写第j个项目;

litc学长出的题,引文最小割题目做的少,想的少,考试时一直没写出来,按题解自己写了个ISAP,已通过所有测试点。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
int n,m,S,T,A,B,ecnt,first[600000];
struct Edge{int u,v,nxt,cap,flow;}e[1050000];
bool vis[600000];
int q[600000],d[600000],p[600000],num[600000],cur[600000];
void Link(int u,int v,ll w)
{
     e[++ecnt].u=u,e[ecnt].v=v,e[ecnt].cap=w,e[ecnt].flow=0;
     e[ecnt].nxt=first[u],first[u]=ecnt;
     e[++ecnt].u=v,e[ecnt].v=u,e[ecnt].cap=0,e[ecnt].flow=0;
     e[ecnt].nxt=first[v],first[v]=ecnt;
}
void bfs()
{
     int head=0,tail=1;
     memset(vis,false,sizeof(vis));
     q[0]=T,d[T]=0,vis[T]=true;
     while(head^tail){
           int now=q[head++];
           for(int i=first[now];i;i=e[i].nxt)
               if(!vis[e[i].u]&&e[i].cap>e[i].flow){
                   vis[e[i].u]=true;
                   d[e[i].u]=d[now]+1;
                   q[tail++]=e[i].u;
               }
     }
}
int Agument()
{
    int x=T,a=0x7fffffff;
    while(x^S){
          a=min(a,e[p[x]].cap-e[p[x]].flow);
          x=e[p[x]].u;
    }
    x=T;
    while(x^S){
          e[p[x]].flow+=(ll)a;
          e[p[x]^1].flow-=(ll)a;
          x=e[p[x]].u;
    }
    return a;
}
ll ISAP()
{
    int x=S;
    ll flow=0;
    bfs();
    memset(num,0,sizeof(num));
    for(int i=S;i<=T;i++)
        num[d[i]]++,cur[i]=first[i];
    while(d[S]<n+1){
          if(!(x^T)){
             flow+=(ll)Agument();
             x=S;
          }
          bool advanced=false;
          for(int i=cur[x];i;i=e[i].nxt)
              if(e[i].cap>e[i].flow&&d[x]==d[e[i].v]+1){
                 advanced=true;
                 cur[x]=p[e[i].v]=i;
                 x=e[i].v;
                 break;
              }
          if(!advanced){
             int mn=n;
             for(int i=first[x];i;i=e[i].nxt)
                 if(e[i].cap>e[i].flow)
                    mn=min(mn,d[e[i].v]);
             if(--num[d[x]]==0)break;
             num[d[x]=mn+1]++;
             cur[x]=first[x];
             if(x^S)x=e[p[x]].u;
          }
    }
    return flow;
}
int main()
{
    freopen("project.in","r",stdin);
    freopen("project.out","w",stdout);
    scanf("%d%d",&n,&m);
    S=0,T=n+1,ecnt=1;
    for(int i=1;i<=n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            Link(S,i,x);
            Link(i,T,y);
    }
    for(int i=1;i<=m;i++){
            int x,y,c,d;
            scanf("%d%d%d%d",&x,&y,&c,&d);
            Link(x,y,d);
            Link(y,x,c);
    }
    printf("%I64d\n",ISAP());//output 'min cut';
    fclose(stdin);fclose(stdout);
    return 0;
}



 

posted @ 2016-07-20 21:03  keshuqi  阅读(142)  评论(0编辑  收藏  举报