zzuli 2131 Can Win dinic+链式前向星(难点:抽象出网络模型+建边)

2131: Can Win

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 431  Solved: 50

SubmitStatusWeb Board

Description

Zhc很喜欢看某个竞技比赛,比赛的规则是这样的:队伍分成AB两组进行比赛,除了组内比赛,两组之间还会进行一定的比赛,每场比赛赢者得1分,输者不得分,没有平局的情况。 在A组里面Zhc有一支自己非常喜欢的队伍,现在比赛已经进行到一半了,Zhc想知道,他支持的那支队伍有没有可能获得最终的胜利(A组最高分即为胜利,允许多支队伍同时最高分)

 

Input

 第一行输入样例组数T<=110

每组样例第一行输入A组队伍数量n<=400,以及Zhc支持的队伍编号(1-n)K<=n

第二行按编号输入A组各队伍目前的成绩Mark[i]<= 300000

第三行按编号输入A组各队伍剩余比赛总场数Cnt[i]<= 300000

下面有一个N*N的矩阵,其中A[i][j]代表编号i的队伍跟编号j的队伍剩余比赛场数A[i][j]<=100

 

Output

 对每组样例输出”Yes”或者”No”(不用输出引号)代表Zhc支持的队伍能获得最终的胜利,换行处理

 

Sample Input

12 15 62 20 11 0

Sample Output

Yes
思路:

已经AC的正确代码:
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int MAXN=400+400*400+2;
  4 const int MAXM=400*400*6+400*2+5;
  5 const int INF=0x3f3f3f3f;
  6 struct Edge
  7 {
  8     int v,f,next;
  9 }edge[MAXM];
 10 int cnt;
 11 int first[MAXN],level[MAXN];
 12 int q[MAXN];
 13 void init()
 14 {
 15     cnt=0;
 16     memset(first,-1,sizeof(first));
 17 }
 18 void addedge(int u, int v, int f)
 19 {
 20     edge[cnt].v=v,edge[cnt].f=f;
 21     edge[cnt].next=first[u],first[u]=cnt++;
 22     edge[cnt].v=u,edge[cnt].f=0;
 23     edge[cnt].next=first[v],first[v]=cnt++;
 24 }
 25 int bfs(int s, int t)
 26 {
 27     memset(level,0,sizeof(level));
 28     level[s]=1;
 29     int front=0,rear=1;
 30     q[front]=s;
 31     while(front<rear)
 32     {
 33         int x=q[front++];
 34         if(x==t) return 1;
 35         for(int e=first[x];e!=-1;e=edge[e].next)
 36         {
 37             int v=edge[e].v,f=edge[e].f;
 38             if(!level[v]&&f)
 39             {
 40                 level[v]=level[x]+1;
 41                 q[rear++]=v;
 42             }
 43         }
 44     }
 45     return 0;
 46 }
 47 int dfs(int u, int maxf, int t)
 48 {
 49     if(u==t) return maxf;
 50     int ret=0;
 51     for(int e=first[u];e!=-1;e=edge[e].next)
 52     {
 53         int v=edge[e].v,f=edge[e].f;
 54         if(level[u]+1==level[v]&&f)
 55         {
 56             int Min=min(maxf-ret,f);
 57             f=dfs(v,Min,t);
 58             edge[e].f-=f;
 59             edge[e^1].f+=f;
 60             ret+=f;
 61             if(ret==maxf) return ret;
 62         }
 63     }
 64     return ret;
 65 }
 66 int Dinic(int s, int t)
 67 {
 68     int ans=0;
 69     while(bfs(s,t)) ans+=dfs(s,INF,t);
 70     return ans;
 71 }
 72 int main() {
 73     int T;
 74     scanf("%d",&T);
 75     while(T--) {
 76         int n,k;scanf("%d%d",&n,&k);
 77         int mark[405];
 78         for(int i=1;i<=n;++i) scanf("%d",&mark[i]);
 79         int cnt,highscore;
 80         for(int i=1;i<=n;++i) {
 81             scanf("%d",&cnt);
 82             if(i==k) {
 83                 highscore=mark[k]+cnt;
 84             }
 85         }
 86         int s=0,t=n*n+n+1;
 87         init();
 88         int score,sum=0;
 89         for(int i=1;i<=n;++i) {
 90             for(int j=1;j<=n;++j) {
 91                 scanf("%d",&score);
 92                 if(score==0||i==k||j==k) continue;
 93                 addedge(s,i*n+j,score);
 94                 addedge(i*n+j,i,score);
 95                 addedge(i*n+j,j,score);
 96                 sum+=score;
 97             }
 98         }
 99         bool flag=true;
100         for(int i=1;i<=n;++i) {
101             if(i==k) continue;
102             if(mark[i]>highscore) {
103                 flag=false;break;
104             }
105             addedge(i,t,highscore-mark[i]);
106         }
107         if(flag==false) {
108             printf("No\n");continue;
109         }
110         int result=Dinic(s,t);
111         if(result==sum) printf("Yes\n");
112         else printf("No\n");
113     }
114     return 0;
115 }
View Code
之前的错误代码:(不清楚哪里错了,如果看出来请指教)sap+链式前向星
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=400+400*400+2;
  4 const int maxm=400*400*6+400*2+5;
  5 const int INF=0x3f3f3f3f;
  6 struct node {
  7     int c,to,next;
  8 }edges[maxm];
  9 int head[maxn];
 10 int numh[maxn],h[maxn],curedges[maxn],pre[maxn];
 11 int cnt;
 12 void init() {
 13     cnt=0;
 14     memset(head,-1,sizeof(head));
 15 }
 16 void addedge(int u, int v, int c) {
 17     edges[cnt].to=v;edges[cnt].c=c;edges[cnt].next=head[u];head[u]=cnt++;
 18     edges[cnt].to=u;edges[cnt].c=0;edges[cnt].next=head[v];head[v]=cnt++;
 19 }
 20 int sap(int source, int sink, int N) {
 21     int cur_flow,flow_ans=0,u,tmp,neck,i;
 22     memset(h,0,sizeof(h));
 23     memset(numh,0,sizeof(numh));
 24     memset(pre,-1,sizeof(pre));
 25     for(int i=1;i<=N;++i) curedges[i]=head[i];
 26     numh[0]=N;
 27     u=source;
 28     while(h[source]<N) {
 29         if(u==sink) {
 30             cur_flow=INF;
 31             for(i=source;i!=sink;i=edges[curedges[i]].to) {
 32                 if(cur_flow>edges[curedges[i]].c) {
 33                     neck=i;
 34                     cur_flow=edges[curedges[i]].c;
 35                 }
 36             }
 37             for(i=source;i!=sink;i=edges[curedges[i]].to) {
 38                 tmp=curedges[i];
 39                 edges[tmp].c-=cur_flow;
 40                 edges[tmp^1].c+=cur_flow;
 41             }
 42             flow_ans+=cur_flow;
 43             u=neck;
 44         }
 45         for(i=curedges[u];i!=-1;i=edges[i].next) {
 46             if(edges[i].c&&h[u]==h[edges[i].to]+1)
 47                 break;
 48         }
 49         if(i!=-1) {
 50             curedges[u]=i;
 51             pre[edges[i].to]=u;
 52             u=edges[i].to;
 53         } else {
 54             if(0==--numh[h[u]]) break;
 55             curedges[u]=head[u];
 56             for(tmp=N,i=head[u];i!=-1;i=edges[i].next) {
 57                 if(edges[i].c) {
 58                     tmp=min(tmp,edges[i].to);
 59                 }
 60             }
 61             h[u]=tmp+1;
 62             ++numh[h[u]];
 63             if(u!=source) u=pre[u];
 64         }
 65     }
 66     return flow_ans;
 67 }
 68 int main() {
 69     int T;
 70     scanf("%d",&T);
 71     while(T--) {
 72         int n,k;scanf("%d%d",&n,&k);
 73         int mark[405];
 74         for(int i=1;i<=n;++i) scanf("%d",&mark[i]);
 75         int cnt,highscore;
 76         for(int i=1;i<=n;++i) {
 77             scanf("%d",&cnt);
 78             if(i==k) {
 79                 highscore=mark[k]+cnt;
 80             }
 81         }
 82         int s=0,t=n*n+n+1;
 83         init();
 84         int score,sum=0;
 85         for(int i=1;i<=n;++i) {
 86             for(int j=1;j<=n;++j) {
 87                 scanf("%d",&score);
 88                 if(score==0||i==k||j==k) continue;
 89                 addedge(s,i*n+j,score);
 90                 addedge(i*n+j,i,score);
 91                 addedge(i*n+j,j,score);
 92                 sum+=score;
 93             }
 94         }
 95         bool flag=true;
 96         for(int i=1;i<=n;++i) {
 97             if(i==k) continue;
 98             if(mark[i]>highscore) {
 99                 flag=false;break;
100             }
101             addedge(i,t,highscore-mark[i]);
102         }
103         if(flag==false) {
104             printf("No\n");continue;
105         }
106         int result=sap(s,t,t+1);
107         if(result==sum) printf("Yes\n");
108         else printf("No\n");
109     }
110     return 0;
111 }
View Code

 

posted @ 2017-11-03 01:43  lemonsbiscuit  阅读(144)  评论(0编辑  收藏  举报