zoukankan      html  css  js  c++  java
  • Cogs 329. K- 联赛(最大流)

    1. K- 联赛
      ★★★ 输入文件:kleague.in 输出文件:kleague.out 简单对比
      时间限制:1 s 内存限制:32 MB
      【问题描述】
      K- 联赛职业足球俱乐部的球迷们都是有组织的训练有素的啦啦队员,就像红魔啦啦队一样 (2002 年韩日世界杯上韩国队的啦啦队 ) 。这个赛季,经过很多场比赛以后,球迷们希望知道他们支持的球队是否还有机会赢得最后的联赛冠军。换句话说,球队是否可以通过某种特定的比赛结果最终取得最高的积分 ( 获胜场次最多 ) 。 ( 允许出现多支队并列第一的情况。 )
      现在,给出每个队的胜负场数, w i 和 d j ,分别表示 team i 的胜场和负场 (1 ≤ i ≤ n) 。还给出 a i,j ,表示 team i 和 team j 之间还剩多少场比赛要进行 (1 ≤ i , j ≤ n) 。这里, n 表示参加联赛的队数,所有的队分别用 l , 2 ,…, n 来编号。你的任务是找出所有还有可能获得冠军的球队。
      所有队参加的比赛数是相同的,并且为了简化问题,你可以认为不存在平局 ( 比赛结果只有胜或负两种 ) 。
      【输入】
      第一行一个整数 n (1 ≤ n ≤ 25) ,表示联赛中的队数。
      第二行 2n 个数, w 1 , d 1 , w 2 , d 2 ,…, w n , d n ,所有的数都不超过 100 。
      第三行 n^2 个数, a 1,1 , a 1,2 ,…, a 1,n , a 2,1 , a 2,2 , …, a 2,n ,…, a n,1 , a n,2 ,…, a n,m , 所有的数都不超过 10 。 a i,j =a j,i ,如果 i=j ,则 a i,j =0 。
      【输出】
      仅一行,输出所有可能获得冠军的球队,按其编号升序输出,中间用空格分隔。
      【样例 1】
      kleague.in
      3
      2 0 1 1 0 2
      0 2 2 2 0 2 2 2 0
      kleague.out
      1 2 3
      【样例 2】
      kleague.in
      3
      4 0 2 2 0 4
      0 1 1 1 0 1 1 1 0
      kleague.out
      1 2
      【样例 3 】
      kleague.in
      4
      0 3 3 1 1 3 3 0
      0 0 0 2 0 0 1 0 0 1 0 0 2 0 0 0
      kleague.out
      2 4
    /*
    最大流.
    可行流判定.
    我们只关心胜利的次数.
    如果看清数据范围的话,就往这方面想了orz.
    对于每个点都做一次判定.
    搞一个二分图,左边是团队,右边是比赛.
    这样的话我们去判定一个是否可行的时候
    如果存在x可以夺冠的局面,那么它必然存在剩下的比赛
    全部胜利且获得总分最高的局面. 
    我们让判定的那个团队的剩余比赛都胜利的情况下,
    给每个团队分配最多tot+w[x]-w[i]的流量. 
    让比赛分配胜利次数看是否能跑出可行流.
    最后看看是否满流.
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define MAXN 2001
    #define INF 1e9
    using namespace std;
    int n,m,ans,tot,cnt,total,cut,S,T,head[MAXN],dis[MAXN],w[MAXN],c[MAXN][MAXN];
    struct edge{int v,next,c;}e[MAXN*3];
    queue<int>q;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v,int c)
    {
        e[++cut].v=v;e[cut].c=c;e[cut].next=head[u];head[u]=cut;
        e[++cut].v=u;e[cut].c=0;e[cut].next=head[v];head[v]=cut;
    }
    bool bfs()
    {
        q.push(S);
        for(int i=S;i<=T;i++) dis[i]=-1;dis[S]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].next)
            {
                if(dis[e[i].v]==-1&&e[i].c)
                {
                    dis[e[i].v]=dis[u]+1;
                    q.push(e[i].v); 
                }
            }
         }
        return dis[T]!=-1;
    }
    int dfs(int u,int y)
    {
        if(u==T) return y;
        int rest=0;
        for(int i=head[u];i&&rest<y;i=e[i].next)
        {
            if(dis[e[i].v]==dis[u]+1&&e[i].c)
            {
                int x=dfs(e[i].v,min(y-rest,e[i].c));
                rest+=x;
                e[i].c-=x;
                e[i^1].c+=x;
            }
        }
        if(!rest) dis[u]=-1;
        return rest;
    }
    void dinic()
    {
        while(bfs()) ans+=dfs(S,INF);
        return ;
    }
    void Clear()
    {
        memset(head,0,sizeof head);
        cut=1;tot=ans=0,cnt=0;
    }
    bool check(int x)
    {
        Clear();S=0,T=n+n*n+1;
        for(int i=1;i<=n;i++) tot+=c[x][i];
        for(int i=1;i<=n;i++) if(w[i]>tot+w[x]) return false;
        for(int i=1;i<=n;i++)
        {
            if(i==x) continue;
            add(S,i,tot+w[x]-w[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(i==x) continue;
            for(int j=1;j<=i-1;j++)
             {
                if(i==j||j==x||!c[i][j]) continue;
                cnt++;
                add(i,n+cnt,INF);
                add(j,n+cnt,INF);
                add(n+cnt,T,c[i][j]);
            }
        }
        dinic();
        for(int i=head[T];i;i=e[i].next)
          if(e[i^1].c) return false;
        //if(ans==total-w[x]) return true;
        return true;
    }
    int main()
    {
        freopen("kleague.in","r",stdin);
        freopen("kleague.out","w",stdout);
        int x,hhh;
        n=read();
        for(int i=1;i<=n;i++) w[i]=read(),hhh=read();
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++) 
            c[i][j]=read(),total+=c[i][j];
        for(int i=1;i<=n;i++) if(check(i)) printf("%d ",i);
        return 0;
    }
  • 相关阅读:
    pdf .js和tableexport.js使用时遇到的2问题。
    一个基础的问题 多个$(function(){})里面的函数 为什么在下一个$(function(){})里没法执行。
    关于emoji表情,支持在app端发送web端显示,web端发送给app端显示,web与wap端互相显示。
    $.isEmptyObject() 判断对象是否为空
    Access数据库参数没值
    C#导入EXCEL数据
    [IE兼容性] Table 之边框 (IE6 IE7 IE8(Q) 中 cellspacing 属性在重合的边框模型的表格中仍然有效)
    META标签的NAME变量
    控制台应用程序中Main函数的args参数
    无法为表空间 ***中的段创建 INITIAL 区
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068042.html
Copyright © 2011-2022 走看看