UVALive - 6887 Book Club 有向环的路径覆盖

题目链接:

http://acm.hust.edu.cn/vjudge/problem/129727

D - Book Club

Time Limit: 5000MS

题意

给你一个无自环的有向图,问你最后能不能将每个点都划分在若干个有向环里(每个点最后只能属于一个环)。

题解

这题一开始思路就跑偏了,想到连通分量去了。。orz
后来仔细一想,这不是边的分配问题吗!!!首先入度和出度可以分开考虑的,我们只需要考虑每个点的出度就行了,如果一个点的出度只有1,那就显然只能连它了,但是如果它有多个出边,那么这就变成一个匹配问题了!!!,自然可以想到二分匹配去的呀。
我们把v拆成v,v',如果v->u,我们就连边v->u'。 图建完之后跑一遍二分图最大匹配,如果最大匹配==n,那么说明每个点都会属于一个环中!!!
(其实这题就是一个有向环的路径覆盖呀!)

代码

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<stack>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;

//start----------------------------------------------------------------------

const int maxn=1e4+10;

vector<int> G[maxn];
int n,m;

int lef[maxn],vis[maxn];
bool match(int u){
	rep(i,0,G[u].size()){
		int v=G[u][i];
		if(!vis[v]){
			vis[v]=1;
			if(lef[v]==-1||match(lef[v])){
				lef[v]=u; return true;
			}
		}
	}
	return false;
}

void init(){
	rep(i,0,n+1) G[i].clear();
	clr(lef,-1);
}

int main() {
    while(scanf("%d%d",&n,&m)==2&&n){
    	init();
    	rep(i,0,m){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		G[u].push_back(v);
		}
		
		int ans=0;
		rep(i,0,n){
			clr(vis,0);
			if(match(i)) ans++;
		}

		if(ans==n) puts("YES");
		else puts("NO");
	}
    return 0;
}

//end-----------------------------------------------------------------------
posted @ 2016-08-16 00:42  fenicnn  阅读(406)  评论(0编辑  收藏  举报