URAL - 1736 (最大流)

来源:互联网 发布:类似maka的软件 编辑:程序博客网 时间:2024/06/05 12:00

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 3n(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

inputoutput
48 7 2 1
CORRECT2 <= 13 >= 41 > 34 < 21 > 42 > 3
48 8 1 1
INCORRECT
Problem Author: Alexander Ipatov (prepared by Igor Chevdar)
Problem Source: XIV Open USU Championship

   从源点向每场比赛连一条容量为3的边,每场比赛向两只队分别连容量为3的边,每支队向汇点连边,容量为这支队的最终得分。若最大流为3n*(n-1)/2,说明存在一个合法的分配方案。这题是一个网络流解构造性问题的题目,虽然图的点数较多,但依然跑的挺快的。比赛时遇到这样的题目,不妨用网络流一试。

#include<cstdio>#include<map>#include<queue>#include<cstring>#include<iostream>#include<algorithm>#include<vector>#include<list>#include<set>#include<cmath>using namespace std;const int maxn = 1e5 + 5;const int INF = 1e9;const double eps = 1e-6;typedef unsigned long long ULL;typedef long long LL;typedef pair<int, int> P;#define fi first#define se secondstruct Edge {  int from, to, cap, flow;};struct Dinic {  int n, m, s, t;  vector<Edge> edges;    // 边数的两倍  vector<int> G[maxn];   // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号  bool vis[maxn];        // BFS使用  int d[maxn];           // 从起点到i的距离  int cur[maxn];         // 当前弧指针  void ClearAll(int n) {    for(int i = 0; i < n; i++) G[i].clear();    edges.clear();  }  void ClearFlow() {    for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;  }  void AddEdge(int from, int to, int cap) {    //cout << from << ' ' << to << ' ' << cap << endl;    edges.push_back((Edge){from, to, cap, 0});    edges.push_back((Edge){to, from, 0, 0});    m = edges.size();    G[from].push_back(m-2);    G[to].push_back(m-1);  }  bool BFS() {    memset(vis, 0, sizeof(vis));    queue<int> Q;    Q.push(s);    vis[s] = 1;    d[s] = 0;    while(!Q.empty()) {      int x = Q.front(); Q.pop();      for(int i = 0; i < G[x].size(); i++) {        Edge& e = edges[G[x][i]];        if(!vis[e.to] && e.cap > e.flow) {          vis[e.to] = 1;          d[e.to] = d[x] + 1;          Q.push(e.to);        }      }    }    return vis[t];  }  int DFS(int x, int a) {    if(x == t || a == 0) return a;    int flow = 0, f;    for(int& i = cur[x]; i < G[x].size(); i++) {      Edge& e = edges[G[x][i]];      if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) {        e.flow += f;        edges[G[x][i]^1].flow -= f;        flow += f;        a -= f;        if(a == 0) break;      }    }    return flow;  }  int Maxflow(int s, int t) {    this->s = s; this->t = t;    int flow = 0;    while(BFS()) {      memset(cur, 0, sizeof(cur));      flow += DFS(s, INF);    }    return flow;  }};Dinic g;int main(){    int n;    while(scanf("%d", &n) != EOF){        int source = 0, sink = n*(n-1)/2 + n + 1;        g.ClearAll(n*(n-1)/2+n+5);        int cnt = 1;        int sum = n*(n-1)/2;        for(int i = 1;i <= n;i++){            for(int j = i+1;j <= n;j++){                g.AddEdge(source, cnt, 3);                g.AddEdge(cnt, sum+i, 3);                g.AddEdge(cnt, sum+j, 3);                cnt++;            }        }        int total = 0;        for(int i = 1;i <= n;i++){            int x;            scanf("%d", &x);            total += x;            g.AddEdge(sum+i, sink, x);        }        if(g.Maxflow(source, sink)==total){            cout << "CORRECT" << endl;            int cnt = 1;            for(int i = 1;i <= n;i++){                for(int j = i+1;j <= n;j++){                    int f1 = -1, f2 = -1;                    for(int u = 0;u < g.G[cnt].size();u++){                        Edge& e = g.edges[g.G[cnt][u]];                        if(e.cap != 0){                            if(f1 == -1)                                f1 = e.flow;                            else                                f2 = e.flow;                        }                    }                    if(f1==3 && f2 == 0){                        cout << i << " > " << j << endl;                    }                    else if(f1 == 2 && f2 == 1){                        cout << i << " >= " << j << endl;                    }                    else if(f1 == 0 && f2 == 3){                        cout << i << " < " << j << endl;                    }                    else{                        cout << i << " <= " << j << endl;                    }                    cnt++;                }            }        }        else            cout << "INCORRECT" << endl;    }    return 0;}


0 0
原创粉丝点击