1. 程式人生 > >瀋陽網路賽F-Fantastic Graph【貪心】or【網路流】

瀋陽網路賽F-Fantastic Graph【貪心】or【網路流】

"Oh, There is a bipartite graph.""Make it Fantastic."

X wants to check whether a bipartite graph is a fantastic graph. He has two fantastic numbers, and he wants to let all the degrees to between the two boundaries. You can pick up several edges from the current graph and try to make the degrees of every point to between the two boundaries. If you pick one edge, the degrees of two end points will both increase by one. Can you help X to check whether it is possible to fix the graph?

Input

There are at most 3030 test cases.

For each test case,The first line contains three integers NN the number of left part graph vertices, MM the number of right part graph vertices, and KK the number of edges ( 1 \le N \le 20001≤N≤2000,0 \le M \le 20000≤M≤2000,0 \le K \le 60000≤K≤6000 ). Vertices are numbered from 11to NN.

The second line contains two numbers L, RL,R (0 \le L \le R \le 300)(0≤L≤R≤300). The two fantastic numbers.

Then KK lines follows, each line containing two numbers UU, VV (1 \le U \le N,1 \le V \le M)(1≤U≤N,1≤V≤M). It shows that there is a directed edge from UU-th spot to VV-th spot.

Note. There may be multiple edges between two vertices.

Output

One line containing a sentence. Begin with the case number. If it is possible to pick some edges to make the graph fantastic, output "Yes"(without quote), else output "No" (without quote).

樣例輸入複製

3 3 7
2 3
1 2
2 3
1 3
3 2
3 3
2 1
2 1
3 3 7
3 4
1 2
2 3
1 3
3 2
3 3
2 1
2 1

樣例輸出複製

Case 1: Yes
Case 2: No

題目來源

題意:

有一個二分圖 每個節點的初始分數為0

每選一條邊 邊的端點的分數都加1

問如果要求最後所有端點的分數都在l和r之間 可不可以做到

思路:

比賽的時候凌曉突然說這個是上下限網路流的模板題

於是一大幫人就想著怎麼改模板 一直到比賽結束都沒有改出來

真的沒想到居然可以貪心 還好名額拿到了......

很簡單的策略:

相當於刪除一些邊 使得節點的度數在l和r之間 最後剩下的邊就是選擇的邊

列舉每條邊 如果u, v的度都大於R 那麼這條邊肯定可以刪掉

如果u的度大於R, v的度小於R卻大於L 那麼這條邊也可以刪掉

同理 uv交換也是

如果本來uv的度就在LR之間 就不用管了

最後檢查每一個節點的度是不是在LR之間 結束

貪心AC:


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<cmath>
#include<cstring>
#include<set>
//#include<bits/stdc++.h>
#define inf 0x7f7f7f7f7f7f7f7f
using namespace std;
typedef long long LL;

const int maxk = 6005;
const int maxn = 4005;
int n, m, k, l, r;
struct edge {
	int u, v;
}e[maxk];
int degree[maxn];

void init()
{
	memset(degree, 0, sizeof(degree));
}

int main()
{
	int cas = 1;
	while (scanf("%d%d%d", &n, &m, &k) != EOF) {
        init();
		scanf("%d%d", &l, &r);
		for (int i = 0; i < k; i++) {
			scanf("%d%d", &e[i].u, &e[i].v);
			e[i].v += n;
			degree[e[i].u]++;
			degree[e[i].v]++;
		}

		for (int i = 0; i < k; i++) {
			int a = e[i].u, b = e[i].v;
			if (degree[a] > r && degree[b] > r) {
				degree[a]--;
				degree[b]--;
			}
			else if (degree[a] > l || degree[b] > l) {
				degree[a]--;
				degree[b]--;
			}
		}

		bool flag = true;
		for (int i = 1; i <= n + m; i++) {
			if (degree[i] > r || degree[i] < l) {
				flag = false;
				break;
			}
		}
		if (flag) {
			printf("Case %d: Yes\n", cas++);
		}
		else {
			printf("Case %d: No\n", cas++);
		}
	}
	return 0;
}

上下限網路流的演算法正在學習中......