[Shoi2007]Vote in good faith

Title Description

There are n children in kindergarten who are going to vote to decide whether to take a nap or not. For them, this issue is not very important, so they decided to show their humility. Although everyone has their own opinions, in order to take care of their friends' ideas, they can also vote against their original wishes. We define the number of conflicts in a vote as the total number of conflicts between good friends plus the number of conflicts with all the people who would like to have conflicts with themselves.

Our question is, how should each child vote to minimize the number of conflicts?

I / O format

Input format:

There are only two integers n, m in the first line of the file, 2 ≤ n ≤ 300, 1 ≤ m ≤ n(n-1)/2. Where n represents the total number of people and M represents the logarithm of good friends. I n the second line of the document, there are n integers. The I integers represent the wishes of the I children. When it is 1, it means that they agree to sleep. When it is 0, it means that they are against sleep. Next, the file has m lines, each with two integers i, J. I, j is a good friend, we guarantee that any two pairs of I, J will not repeat.

Output format:

You only need to output an integer, which is the minimum number of possible conflicts.

Example of input and output

Input example ා 1:

3 3
1 0 0
1 2
1 3
3 2

Output example:

1

Explain

2≤n≤300,1≤m≤n(n-1)/2.

Title Solution

Minimum cut
S for 0, T for 1
If i prefer to cast 0, i will connect an edge with capacity of 1 to T, which means there will be another conflict
If i prefer to vote for 1, then S will connect an edge with capacity of 1 to i, which also means there will be another conflict,
i. If J is a friend, I and j are connected to each other by an edge with a capacity of 1, then I and j are not the same
Run the maximum flow once (i.e. the minimum cut)

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
# define Copy(a, b) memcpy(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(310), __(4e5 + 10), INF(2147483647);

IL ll Read(){
    RG char c = getchar(); RG ll x = 0, z = 1;
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

int n, m, w[__], fst[_], nxt[__], to[__], cnt;
int S, T, lev[_], cur[_], max_flow;
queue <int> Q;

IL void Add(RG int u, RG int v, RG int f){  w[cnt] = f; to[cnt] = v; nxt[cnt] = fst[u]; fst[u] = cnt++;  }

IL int Dfs(RG int u, RG int maxf){
    if(u == T) return maxf;
    RG int ret = 0;
    for(RG int &e = cur[u]; e != -1; e = nxt[e]){
        if(lev[to[e]] != lev[u] + 1 || !w[e]) continue;
        RG int f = Dfs(to[e], min(w[e], maxf - ret));
        ret += f; w[e ^ 1] += f; w[e] -= f;
        if(ret == maxf) break;
    }
    return ret;
}

IL bool Bfs(){
    Fill(lev, 0); lev[S] = 1; Q.push(S);
    while(!Q.empty()){
        RG int u = Q.front(); Q.pop();
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(lev[to[e]] || !w[e]) continue;
            lev[to[e]] = lev[u] + 1;
            Q.push(to[e]);
        }
    }
    return lev[T];
}

int main(RG int argc, RG char* argv[]){
    n = Read(); m = Read(); Fill(fst, -1); T = n + 1;
    for(RG int i = 1, a; i <= n; i++){
        a = Read();
        if(a) Add(S, i, 1), Add(i, S, 0);
        else Add(i, T, 1), Add(T, i, 0);
    }
    for(RG int i = 1, a, b; i <= m; i++){
        a = Read(), b = Read();
        Add(a, b, 1); Add(b, a, 0);
        Add(b, a, 1); Add(a, b, 0);
    }
    while(Bfs()) Copy(cur, fst), max_flow += Dfs(S, INF);
    printf("%d\n", max_flow);
    return 0;
}

Posted on Mon, 04 May 2020 20:06:43 -0400 by faydra92