天天看點

BZOJ 2718/1533 Violet 4 畢業旅行

2718: [Violet 4]畢業旅行

Time Limit: 10 Sec  Memory Limit: 128 MB

Submit: 676  Solved: 391

[Submit][Status][Discuss]

Description

BZOJ 2718/1533 Violet 4 畢業旅行

Input

BZOJ 2718/1533 Violet 4 畢業旅行

Output

最多可選多少景點

Sample Input

7 6

1 2

2 3

5 4

4 3

3 6

6 7

Sample Output

2

HINT

BZOJ 2718/1533 Violet 4 畢業旅行

Source

Ctsc2008 River & ural 1533. Fat Hobbits

  用floyed傳遞背包求出那兩個點之間可以到達 剩下的不就是在一個二分圖中求出最大獨立集麼麼?最大獨立集=總點數-二分圖最大比對數(也就是最小點覆寫) dinic跑二分圖最大比對數的複雜度是O(n*sqrt(n))

#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
using namespace std;
inline int read(){
	int x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int MAXN=5e4+10;
struct node{
	int y,next,flow,back;
}e[MAXN];
int linkk[MAXN],len,n,head,tail,q[MAXN],level[1000],s,t,v[210][210],m;
inline void insert(int x,int y,int f){
	e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].back=len+1;e[len].flow=f;
	e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;e[len].back=len-1;e[len].flow=0;
}
inline bool getlevel(){
	head=tail=0;
	memset(level,-1,sizeof(level));
	q[++tail]=s;level[s]=0;
	while(head<tail){
		int tn=q[++head];
		for(int i=linkk[tn];i;i=e[i].next){
			if(e[i].flow&&level[e[i].y]==-1){
				level[e[i].y]=level[tn]+1;
				q[++tail]=e[i].y;
			}
		}
	}
	return level[t]>=0;
}
inline int getmaxflow(int x,int flow){
	if(x==t) return flow;
	int f=0,d;
	for(int i=linkk[x];i;i=e[i].next){
		if(level[e[i].y]==level[x]+1&&e[i].flow){
			if(d=getmaxflow(e[i].y,min(flow-f,e[i].flow))){
				e[i].flow-=d;f+=d;e[e[i].back].flow+=d;
				if(f==flow) return f;
			}
		}
	}
	if(f==0) level[x]=-1;
	return f;
}
inline int dinic(){
	int ans=0,d;
	while(getlevel()){
		while(d=getmaxflow(s,inf)) ans+=d;
	}
	return ans;
}
void build(){
	s=0,t=2*n+1;
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				v[i][j]|=(v[i][k]&v[k][j]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		insert(s,i,1);insert(i+n,t,1);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(v[i][j]) insert(i,j+n,inf);
		}
	}
}
int main(){
	n=read();m=read();
	for(int i=1;i<=m;i++){
		int x=read();int y=read();
		v[x][y]=1;
	}
	build();
	printf("%d\n",n-dinic());
	return 0;
}
           

  

轉載于:https://www.cnblogs.com/something-for-nothing/p/8975905.html