【CF】304 E. Soldier and Traveling

基础网络流,增加s和t,同时对于每个结点分裂为流入结点和流出结点。EK求最大流,判断最大流是否等于当前总人数。

  1 /* 304E */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 using namespace std;
 20 //#pragma comment(linker,"/STACK:102400000,1024000")
 21
 22 #define rep(i, a, n)     for (int i=a;i<n;++i)
 23 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 24 #define pb                 push_back
 25 #define mp                 make_pair
 26 #define all(x)             (x).begin(),(x).end()
 27 #define SZ(x)             ((int)(x).size())
 28 #define lson            l, mid, rt<<1
 29 #define rson            mid+1, r, rt<<1|1
 30
 31 const int maxn = 205;
 32 int F[maxn][maxn];
 33 int P[maxn], a[maxn];
 34 bool visit[maxn];
 35 int ans[maxn][maxn];
 36 int ai[maxn], bi[maxn], ci[maxn];
 37 int n, m, s = 0, t;
 38 bool flag = true;
 39
 40 bool bfs() {
 41     int u, v;
 42     queue<int> Q;
 43
 44     memset(a, 0, sizeof(a));
 45     a[s] = INT_MAX;
 46     Q.push(s);
 47     P[s] = s;
 48
 49     while (!Q.empty()) {
 50         u = Q.front();
 51         Q.pop();
 52         for (v=0; v<=t; ++v) {
 53             if (!a[v] && F[u][v]) {
 54                 P[v] = u;
 55                 Q.push(v);
 56                 a[v] = min(a[u], F[u][v]);
 57             }
 58         }
 59     }
 60
 61     return a[t]==0;
 62 }
 63
 64 int Edmonds_Karp() {
 65     int u, v;
 66     int ans = 0;
 67
 68     while (1) {
 69         if (bfs())
 70             break;
 71         for (u=t,v=P[u]; u!=s; u=v, v=P[u]) {
 72             F[u][v] += a[t];
 73             F[v][u] -= a[t];
 74         }
 75         ans += a[t];
 76     }
 77     return ans;
 78 }
 79
 80 int main() {
 81     int i, j, k;
 82     int s1, s2;
 83
 84     #ifndef ONLINE_JUDGE
 85         freopen("data.in", "r", stdin);
 86         freopen("data.out", "w", stdout);
 87     #endif
 88
 89     scanf("%d %d", &n, &m);
 90     t = n+n+1;
 91     memset(F, 0, sizeof(F));
 92     memset(ans, 0, sizeof(ans));
 93     s1 = s2 = 0;
 94
 95     for (i=1; i<=n; ++i) {
 96         scanf("%d", &ai[i]);
 97         s1 += ai[i];
 98         F[0][i] = ai[i];
 99     }
100
101     for (i=1; i<=n; ++i) {
102         scanf("%d", &bi[i]);
103         s2 += bi[i];
104         F[i][i+n] = INT_MAX;
105         F[i+n][t] = bi[i];
106     }
107
108     for (i=0; i<m; ++i) {
109         scanf("%d %d", &j, &k);
110         F[j][k+n] = INT_MAX;
111         F[k][j+n] = INT_MAX;
112     }
113
114     flag = s1==s2;
115     if (flag) {
116         flag = Edmonds_Karp() == s1;
117     }
118
119     if (flag) {
120         for (i=1; i<=n; ++i)
121             for (j=n+1; j<t; ++j)
122                 ans[i][j-n] = F[j][i];
123         puts("YES");
124         for (i=1; i<=n; ++i) {
125             for (j=1; j<=n; ++j)
126                 printf("%d ", ans[i][j]);
127             putchar(‘\n‘);
128         }
129     } else {
130         puts("NO");
131     }
132
133     #ifndef ONLINE_JUDGE
134         printf("time = %d.\n", (int)clock());
135     #endif
136
137     return 0;
138 }
时间: 2024-12-28 16:26:33

【CF】304 E. Soldier and Traveling的相关文章

【CF】38E Let&#39;s Go Rolling! (dp)

前言 这题还是有点意思的. 题意: 给你 \(n\) (\(n<=3000\)) 个弹珠,它们位于数轴上.给你弹珠的坐标 \(x_i\) 在弹珠 \(i\) 上面花费 \(C_i\) 的钱 可以使弹珠在原地不动 (\(-10^9<=x_i,C_i<=10^9\)),游戏开始时,所有的弹珠向左滚动,直到碰到定在原地不动的弹珠,其花费是其滚动的距离.总花费=开始前的花费+弹珠滚动的花费,问最小的花费是多少 题解 首先划分出阶段,,我们可以先将弹珠排序,前 \(i\) 个弹珠,最后一个固定的弹

【CF】codeforces round 369(div2)

*明早起来再贴代码 A [题意] 给定n*5的方格 将横向的相邻两个变成+输出   [题解] ...   B [题意] 一个n*n的正整数矩阵,有且仅有一个数为0 ,在这个位置填上一个数,使得每一列的和 每一行的和 两条对角线各自的和都相等 输出这个数   [题解]sb题.暴力一下.注意细节,否则你就像这样 (不是本人   C [题意] 一排点,用1~n表示,熊孩子要给这些点上色.最初每个点的颜色为ci.一共有m种颜色,如果ci=0表示这个点最初无色. 熊孩子们需要给最初为无色的点涂上色,往第i

【CF】Codeforces Round #361 (Div. 2)

难得有想法写一整套题解 首先想说的是,这场CF,我感觉是div2极为不错的一场(对于中档选手<因为我就出了三题,还掉了一个-- 说笑了,感觉这一场很耐人寻味.就是那种抓破头皮想不出,知道做法后细细品味,有种   哦~~~~~这样啊~~~~好神奇!!! 的感觉 首先..秀一下战绩 不多说了 都在题里 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ A. Mike and Cellphone time limit per test 1 second memory limit per test 256 megaby

【CF】掉分总结

比赛总结 前情提要 自从前段时间连续掉分,就心态崩了,还是自己太菜,一直想写个总结,看看这几场比赛都干了啥,以后准备怎么办.鸽了这么久的总结,是该写写了. 这是正文 首先大致提一下情感曲线(菜的真实): 那一晚,那一夜,sc大佬突然qq发消息给我,"打cf吗",我眉头一紧,这个cf莫非是穿越火线?又一想大佬才不会玩这种游戏,又一想,难道是codeforces?我颤颤巍巍的回了"codeforces?",大佬回的很快,扔给我了个链接,并说"这是616,你做吧

【CF】121 Div.1 C. Fools and Roads

题意是给定一棵树.同时,给定如下k个查询: 给出任意两点u,v,对u到v的路径所经过的边进行加计数. k个查询后,分别输出各边的计数之和. 思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.然后dfs求解各边的计数. 1 /* 191C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #inc

【CF】207 Div.1 B.Xenia and Hamming

这题目一看很牛逼,其实非常easy.求求最小公倍数,最大公约数,均摊复杂度其实就是O(n). 1 /* 356B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <dequ

【CF】283D Tennis Game

枚举t加二分判断当前t是否可行,同时求出s.注意不能说|a[n]| <= |3-a[n]|就证明无解,开始就是wa在这儿了.可以简单想象成每当a[n]赢的时候,两人都打的难解难分(仅多赢一轮):而每当a[n]输的时候,一轮都没赢.在这个前提下,显然存在|a[n]| <= |3-a[n]|. 1 /* 283D */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include &l

【CF】196 Div.2 Book of Evil

显然这个图是一课树,看着题目首先联想到LCA(肯定是可以解的).但是看了一下数据大小,应该会TLE.然后,忽然想到一个前面做过的题目,大概是在一定条件下树中某结点旋转成为根后查询最长路径.结果灵感就来了,主要思路是对于每个结点,第一次dfs得到两个变量到P结点的最大值以及次大值.然后,第二次dfs对于当前结点u,u到它的子树中P类结点的最大距离已知(nd[u].mx),那么除u的其他结点v到P类结点的最大距离加上v到u的距离和的最大值为pmx,可以通过每次深搜计算出来,只要d大于等于两者的最大值

【CF】3B Lorry

这道题目网上有几个题解,均有问题.其实就是简单的贪心+排序,没必要做的那么复杂.一旦tot+curv > v时,显然curv==2, 有三种可能:(1)取出最小的curv==1的pp,装入当前的p:(2)取出后续最大的curv==1的p,并且装入:(3)当前已经是最优的(即后续不存在curv==1的类型),同时前一个的pp比当前的p更优.(这种情况不需要特判) 1 /* 3B */ 2 #include <iostream> 3 #include <string> 4 #in