• 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
    ");continue;
    109         }
    110         int result=Dinic(s,t);
    111         if(result==sum) printf("Yes
    ");
    112         else printf("No
    ");
    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
    ");continue;
    105         }
    106         int result=sap(s,t,t+1);
    107         if(result==sum) printf("Yes
    ");
    108         else printf("No
    ");
    109     }
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    Fix Installing .NET Framework 3.5 failed Error Code 0x800F0954 on Windows 10
    RHEL8安装五笔输入法
    Enable EPEL and Local Repository on RHEL8
    Why is Yum Replaced by DNF?
    检查Linux服务器是否被攻击的常用命令及方法
    IDEA 主题
    IDEA 如何显示一个类中所有的方法
    Appium 安装以及安装过程中遇到的问题
    Maven 如何发布 jar 包到 Nexus 私库
    java泛型的基本使用
  • 原文地址:https://www.cnblogs.com/lemonbiscuit/p/7775974.html
Copyright © 2020-2023  润新知