URAL 1736 Chinese Hockey(网络最大流)

一场比赛在规定时间内比完 胜者3分败者0分,加时赛比完胜者2分败者1分

然后联赛是单循环赛(任何两只队伍比一次),给出了上赛季每只队伍的积分,问你这个积分合不合理,如果合理则要输出方案。

首先我们发现一场比赛的积分固定,然后3分无论怎么分配都能对应一种胜负情况,因此用最大流

将每场比赛和每一只队伍分别抽象成点(比赛点: 1 -至2*n*(n-1)   队伍点 2*n*(n-1)+1 至2*n*(n-1)+n )

源点和每场比赛连 容量3

每场比赛和对应的两只队伍连,容量分别是3

然后每一只队伍和汇点连,容量是这只队伍上赛季积分。

然后最大流判断满流,如果不是满流则不合理

否则根据边上残余网络的容量输出方案。

1736. Chinese Hockey

Time limit: 1.0 second
Memory limit: 64 MB
Sergey and Denis closely followed the Chinese Football Championship, which has just come to an end. They supported the  Katraps and  Komolotiv teams, but, unfortunately, these teams tied for last place in the championship. Sergey was so disappointed that he suggested Denis that they change to hockey fans.
There are  n teams competing in the Chinese Ice Hockey Championship. During the season, each team must play with each other team exactly one game. If a team wins in the regulation time, it gets 3 points and the losing team gets 0 points. If the regulation time is ended in a draw, then the overtime is played. The team that wins in the overtime gets 2 points and the team that loses gets 1 point. A game can't end in a draw in ice hockey.
Denis wants to determine which team he will support. In order to make the choice, he has found a table on the Web in which it is shown for each team how many points it scored in the last year's season. Sergey suspects that there is a mistake in this table because no all-play-all tournament could end with such results. Is Sergey right?

Input

The first line contains the integer  n (2 ≤  n ≤ 200). The second line contains  n space-separated non-negative integers; they are the scores of the teams in the previous championship. The scores are given in the non-increasing order. The sum of all the scores is  3 n( n–1)/2 . None of the teams scored more than  3( n–1)  points.

Output

If Sergey is right and there is a mistake in the table, output “INCORRECT” in the only line. Otherwise, in the first line output “CORRECT” and in the following  n( n–1)/2  lines output the results of the games. Each result must have the form “ i ? j”, where  i and  j are the numbers of the teams that played the game and  ? can be  <<=>=, or  >, which means that the first team lost in the regulation time, lost in the overtime, won in the overtime, and won in the regulation time, respectively. The teams are numbered from 1 to  n in the order in which they are given in the input.

Samples

input output
4
8 7 2 1
CORRECT
2 <= 1
3 >= 4
1 > 3
4 < 2
1 > 4
2 > 3
4
8 8 1 1
INCORRECT

[cpp]  view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<algorithm>  
  5. using namespace std;  
  6.   
  7. #define MAXN 40000  
  8. #define INF 0xFFFFFF  
  9.   
  10. struct edge  
  11. {  
  12.     int to,c,next;  
  13. };  
  14.   
  15. edge e[999999];  
  16. int que[MAXN*100];  
  17. int dis[MAXN],pre[MAXN];  
  18. int head[MAXN],head2[MAXN];  
  19. int st,ed,maxflow;  
  20. int en,n;  
  21.   
  22. void add(int a,int b,int c)  
  23. {  
  24.     e[en].to=b;  
  25.     e[en].c=c;  
  26.     e[en].next=head[a];  
  27.     head[a]=en++;  
  28.     e[en].to=a;  
  29.     e[en].c=0;  
  30.     e[en].next=head[b];  
  31.     head[b]=en++;  
  32. }  
  33.   
  34. bool bfs()  
  35. {  
  36.     memset(dis,-1,sizeof(dis));  
  37.     que[0]=st,dis[st]=1;  
  38.     int t=1,f=0;  
  39.     while(f<t)  
  40.     {  
  41.         int j=que[f++];  
  42.         for(int k=head[j];k!=-1;k=e[k].next)  
  43.         {  
  44.             int i=e[k].to;  
  45.             if(dis[i]==-1 && e[k].c)  
  46.             {  
  47.                 que[t++]=i;  
  48.                 dis[i]=dis[j]+1;  
  49.                 if(i==ed) return true;  
  50.             }  
  51.         }  
  52.     }  
  53.     return false;  
  54. }  
  55.   
  56. int update()  
  57. {  
  58.     int p,flow=INF;  
  59.     for (int i=pre[ed];i!=-1;i=pre[i])  
  60.         if(e[head2[i]].c<flow) p=i,flow=e[head2[i]].c;  
  61.     for (int i=pre[ed];i!=-1;i=pre[i])  
  62.         e[head2[i]].c-=flow,e[head2[i]^1].c+=flow;  
  63.     maxflow+=flow;  
  64.     return p;  
  65. }  
  66.   
  67. void dfs()  
  68. {  
  69.     memset(pre,-1,sizeof(pre));  
  70.     memcpy(head2,head,sizeof(head2));  
  71.     for(int i=st,j;i!=-1;)  
  72.     {  
  73.         int flag=false;  
  74.         for(int k=head[i];k!=-1;k=e[k].next)  
  75.           if(e[k].c && (dis[j=e[k].to]==dis[i]+1) )  
  76.           {  
  77.                 pre[j]=i;  
  78.                 head2[i]=k;  
  79.                 i=j;  
  80.                 flag=true;  
  81.                 if(i==ed)  
  82.                     i=update();  
  83.                 if(flag)  
  84.                     break;  
  85.           }  
  86.         if (!flag) dis[i]=-1,i=pre[i];  
  87.     }  
  88. }  
  89.   
  90. int dinic()  
  91. {  
  92.     maxflow=0;  
  93.     while(bfs())  
  94.         dfs();  
  95.     return maxflow;  
  96. }  
  97.   
  98. int main()  
  99. {  
  100.     while(~scanf("%d",&n))  
  101.     {  
  102.         memset(head,-1,sizeof(head));en=0;  
  103.         int total=n*(n-1)/2+n+1,bas=n*(n-1)/2,cnt=1;  
  104.         st=0,ed=total;  
  105.         for(int i=1;i<=n;i++)  
  106.             for(int j=i+1;j<=n;j++)  
  107.             {  
  108.                 add(cnt,bas+i,3);  
  109.                 add(cnt,bas+j,3);  
  110.                 cnt++;  
  111.             }  
  112.         for(int i=1;i<=n*(n-1)/2;i++) add(st,i,3);  
  113.         int sum=0;bool ok=1;  
  114.         for(int i=n*(n-1)/2+1;i<=n*(n-1)/2+n;i++)  
  115.         {  
  116.             int tmp;  
  117.             scanf("%d",&tmp);  
  118.             sum+=tmp;  
  119.             if(tmp>3*(n-1)) ok=0;  
  120.             add(i,ed,tmp);  
  121.         }  
  122.         dinic();  
  123.         if(!ok||sum!=3*n*(n-1)/2||maxflow!=3*n*(n-1)/2)  
  124.             printf("INCORRECT\n");  
  125.         else  
  126.         {  
  127.             cnt=0;  
  128.             printf("CORRECT\n");  
  129.             for(int i=1;i<=n;i++)  
  130.                 for(int j=i+1;j<=n;j++)  
  131.                 {  
  132.                     int si=3-e[cnt].c;  
  133.                     int sj=3-e[cnt+2].c;  
  134.                     cnt+=4;  
  135.                     if(si==3)  
  136.                         printf("%d > %d\n",i,j);  
  137.                     else if(si==2)  
  138.                         printf("%d >= %d\n",i,j);  
  139.                     else if(si==0)  
  140.                         printf("%d < %d\n",i,j);  
  141.                     else if(si==1)  
  142.                         printf("%d <= %d\n",i,j);  
  143.                 }  
  144.         }  
  145.     }  
  146.     return 0;  
  147. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值