BZOJ 2597: [Wc2007] rock paper scissors minimum cost maximum flow

title

\(~\)
BZOJ 2597
LUOGU 4249
Description

In some one-game match (as in chess, table tennis and badminton singles), we often encounter A is better than B, B beat C and C and to overcome interesting case A, the image of the wish to call it for the rock Paper scissors situation. Sometimes, boring people would relish to count how many such rock paper scissors to happen, that the number of unordered triples (A, B, C), meet one of them wins the game another person, another person won the third person rather than the third person and first person. Note that the order of disorder mean triples of elements is not important, the (A, B, C), (A, C, B), (B, A, C), (B, C, A ), (C, a, B ) and (C, B, a) regarded as the same case.
There are N individuals to participate in a game of this tournament, the provisions of any race should be a game between two people: this total games. Game has been a part of, we want to know, in extreme cases, after the game how many Rock Paper Scissors happens the most. That gives the results of the competition has taken place, and you can arrange any of the rest of the outcome of the game, to get as many rock paper scissors case.

Input

The first line of the input file is an integer N, the number of people participate in the competition.
Followed by a digital matrix of N lines and N columns: total N rows, N columns in each row, with a space between digits.
In the j-th column of numbers (i + 1) line if it is 1, then i j won the game has occurred; and if the number 0, then the game has occurred in the defeated i j; the It figures 2, showing the match between i and j has not yet occurred. Digital numbers on the diagonal matrix, ie (i + 1) row of numbers i-th column are zero, they are merely placeholders, no meaning.
Ensure the legitimate input file, do not collide, the time when i ≠ j, the (i + 1) row and j-th column of the two numbers (j + 1) of the i-th column or row is 2, or a is 0 a is 1.

Output

The first line of the output file is an integer representing the results of the competition in your arrangements, there has been much Rock Paper Scissors situation.
Line 2 starts output file has a digital matrix and the same input file format of N rows and N columns. Of the (i + 1) th row and j describes the results of the competition between the numbers i and j, 1 i represents a win j, l i 0 represents the j, the input matrix is different, in this matrix represents not match figures have not been carried out 2; 0 are the numbers on the diagonal. Output matrix to ensure legal contradictions can not occur.

Sample Input

3
0 1 2
0 0 2
2 2 0

Sample Output

1
0 1 0
0 0 1
1 0 0

HINT

100% of the data, N≤ 100.

analysis

Simplify the meaning of the questions:

Given a graph, a directed edge between each two undirected edges, all undirected edges oriented, so that the drawing number as many as three-membered ring.

From the entire graph \ (n-\) to any point in the take \ (3 \) points, the program number \ (C ^ {3} _ {n} = \ frac {n!} {3! (N-3 )!} = \ {n-FRAC (n--. 1) (n--2)}. 6} {\) ,

If it is not a triple three-membered ring, then there is a point of a \ (2 \) ,

We assume that a point in a degree \ (D \) , then for this point, three-membered rings will reduce the \ (\ FRAC {D (. 1-D)} {2} \) , so the number of three-membered ring : \ (C ^ {. 3} _ {n-} - \ sum_ {I =. 1} ^ NC_ {D [I]} ^ {2} = C ^ {. 3} _ {n-} - \ sum_ {I =. 1} n-^ \ FRAC {D [I] (D [I] -1)} {2} \) ,

So we have to be minimized: \ (\ sum_. 1} ^ {n-I = \ {D FRAC [I] (D [I] -1)} {2} \) ,

How to do it?

If we are to the edge, may allow for a free \ (x \) out of the \ (+ 1 \) , it may allow \ (y \) out of the \ (+ 1 \) , black and white, so we can consider cost flow.

Observation formula \ (\ FRAC {D [I] (D [I] -1)} {2} \) , receiving (HEN) Yi (NaN3) Primary occur Arithmetic Progression summation formula , so we can point to a contribution as \ ((. 1 + 0 + 2 + ...... + D +. 3 [I] -1) \) , so this can be built FIG engage:

  1. To look into each of a point ( described below are used for each side, but when a building is FIG point );
  2. From \ (source S \) to one side of each link capacity \ (1 \) , cost \ (0 \) side;
  3. Undirected edge, this edge to \ (x, y \) were built a capacity \ (1 \) , cost \ (0 \) side;
  4. Directed edges, these edges and \ (y \) to build a capacity of \ (1 \) at a cost of \ (0 \) side.
  5. To each edge (t sink \) \ Even \ (n-\) Article capacity \ (1 \) , a cost of \ (0- (n-1) \) increasing side, showing the top of the arithmetic sequence ( can be expressed in any case a degree);
  6. Finally, the cost of running streams, but \ (EK \) is stuck, run \ (ZKW \) cost flow of it.

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=110,maxm=maxn*maxn,inf=0x3f3f3f3f;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x,char c)
{
    if (!x) *fe++=48;
    if (x<0) *fe++='-', x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) *fe++=ch[num--];
    *fe++=c;
}

int ver[maxm<<3],edge[maxm<<3],Next[maxm<<3],cost[maxm<<3],head[maxm],len=1;
inline void add(int x,int y,int z,int c)
{
    ver[++len]=y,edge[len]=z,cost[len]=c,Next[len]=head[x],head[x]=len;
    ver[++len]=x,edge[len]=0,cost[len]=-c,Next[len]=head[y],head[y]=len;
}

int s,t;
int dist[maxm];
bool vis[maxm];
inline bool spfa()
{
    memset(dist,0x3f,sizeof(dist));
    memset(vis,0,sizeof(vis));
    queue<int>q;q.push(s);
    dist[s]=0,vis[s]=1;
    while (!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for (int i=head[x]; i; i=Next[i])
        {
            if (!edge[i]) continue;
            int y=ver[i];
            if (dist[y]>dist[x]+cost[i])
            {
                dist[y]=dist[x]+cost[i];
                if (!vis[y]) q.push(y),vis[y]=1;
            }
        }
    }
    if (dist[t]==inf) return false;
    else return true;
}

int ans;
inline int get(int x,int low)
{
    vis[x]=1;
    if (x==t) return low;
    int tmp=low;
    for (int i=head[x]; i; i=Next[i])
    {
        int y=ver[i];
        if (edge[i] && dist[y]==dist[x]+cost[i] && (!vis[y] || y==t))
        {
            int a=get(y,min(tmp,edge[i]));
            if (a>0)
            {
                ans+=a*cost[i];
                edge[i]-=a;
                edge[i^1]+=a;
                if (!(tmp-=a)) break;
            }
        }
    }
    return low-tmp;
}

inline void NetFlow()
{
    while (spfa())
    {
        vis[t]=1;
        while (vis[t])
        {
            memset(vis,0,sizeof(vis));
            get(s,inf);
        }
    }
}

int n,a[maxn][maxn];
inline int hs(int i,int j)
{
    return (i-1)*n+j;
}

int main()
{
    read(n); s=0,t=n*n+n+1;
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=n; ++j)
        {
            read(a[i][j]);
            if (i>=j) continue;
            if (a[i][j]==2) add(s,hs(i,j),1,0),add(hs(i,j),i+n*n,1,0),add(hs(i,j),j+n*n,1,0);
            else if (a[i][j]==1) add(s,j+n*n,1,0);
            else add(s,i+n*n,1,0);
        }
    for (int i=1; i<=n; ++i)
        for (int j=0; j<n; ++j) add(i+n*n,t,1,j);
    NetFlow();
    int sum=((n-1)*(n-2)*n)/6;
    write(sum-ans,'\n');
    for (int i=1; i<=n; ++i)
        for (int j=i+1; j<=n; ++j)
        {
            if (a[i][j]<2) continue;
            for (int k=head[hs(i,j)]; k; k=Next[k])
                if (ver[k] && !edge[k]) a[i][j]=(ver[k]-n*n==j),a[j][i]=a[i][j]^1;
        }
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=n; ++j) write(a[i][j],j<n?' ':'\n');
    flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11318263.html