# BZOJ 1934 善意的投票

https://www.lydsy.com/JudgeOnline/problem.php?id=1934

  1 #include<bits/stdc++.h>
2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数，会超时
4 #define Min(a, b) ((a) < (b) ? (a) : (b))
5 #define Mem(a) memset(a, 0, sizeof(a))
6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
8 #define lson ((o)<<1)
9 #define rson ((o)<<1|1)
10 #define Accepted 0
12 using namespace std;
14 {
15     int x=0,f=1;char ch=getchar();
16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 typedef long long ll;
21 const int maxn = 2000 + 10;
22 const int MOD = 1000000007;//const引用更快，宏定义也更快
23 const int INF = 1e9 + 7;
24 const double eps = 1e-6;
25
26 struct edge
27 {
28     int u, v, c, f;
29     edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){}
30 };
31 vector<edge>e;
32 vector<int>G[maxn];
33 int level[maxn];//BFS分层，表示每个点的层数
34 int iter[maxn];//当前弧优化
35 int m;
36 void addedge(int u, int v, int c)
37 {
38     e.push_back(edge(u, v, c, 0));
39     e.push_back(edge(v, u, 0, 0));
40     m = e.size();
41     G[u].push_back(m - 2);
42     G[v].push_back(m - 1);
43 }
44 void BFS(int s)//预处理出level数组
45 //直接BFS到每个点
46 {
47     memset(level, -1, sizeof(level));
48     queue<int>q;
49     level[s] = 0;
50     q.push(s);
51     while(!q.empty())
52     {
53         int u = q.front();
54         q.pop();
55         for(int v = 0; v < G[u].size(); v++)
56         {
57             edge& now = e[G[u][v]];
58             if(now.c > now.f && level[now.v] < 0)
59             {
60                 level[now.v] = level[u] + 1;
61                 q.push(now.v);
62             }
63         }
64     }
65 }
66 int dfs(int u, int t, int f)//DFS寻找增广路
67 {
68     if(u == t)return f;//已经到达源点，返回流量f
69     for(int &v = iter[u]; v < G[u].size(); v++)
70         //这里用iter数组表示每个点目前的弧，这是为了防止在一次寻找增广路的时候，对一些边多次遍历
71         //在每次找增广路的时候，数组要清空
72     {
73         edge &now = e[G[u][v]];
74         if(now.c - now.f > 0 && level[u] < level[now.v])
75             //now.c - now.f > 0表示这条路还未满
76             //level[u] < level[now.v]表示这条路是最短路，一定到达下一层，这就是Dinic算法的思想
77         {
78             int d = dfs(now.v, t, min(f, now.c - now.f));
79             if(d > 0)
80             {
81                 now.f += d;//正向边流量加d
82                 e[G[u][v] ^ 1].f -= d;
83     //反向边减d，此处在存储边的时候两条反向边可以通过^操作直接找到
84                 return d;
85             }
86         }
87     }
88     return 0;
89 }
90 int Maxflow(int s, int t)
91 {
92     int flow = 0;
93     for(;;)
94     {
95         BFS(s);
96         if(level[t] < 0)return flow;//残余网络中到达不了t，增广路不存在
97         memset(iter, 0, sizeof(iter));//清空当前弧数组
98         int f;//记录增广路的可增加的流量
99         while((f = dfs(s, t, INF)) > 0)
100         {
101             flow += f;
102         }
103     }
104     return flow;
105 }
106 int x[maxn];
107 int main()
108 {
109     int n, m;
110     scanf("%d%d", &n, &m);
111     int s = 0, t = n + 1;
112     for(int i = 1; i <= n; i++)
113     {
114         scanf("%d", &x[i]);
117     }
118     while(m--)
119     {
120         int u, v;
121         scanf("%d%d", &u, &v);
122         if(x[u] && !x[v])//u赞成 v反对
129 }