Description
Input
Output
最多可选多少景点
Sample Input
7 6
1 2
2 3
5 4
4 3
3 6
6 7
1 2
2 3
5 4
4 3
3 6
6 7
Sample Output
2
HINT
Source
Ctsc2008 River & ural 1533. Fat Hobbits
首先有个结论。。最小路径覆盖=n-最大二分图匹配
然后这题就没了。。。记得floyd处理下联通
刚好练了一下网络流和匈牙利
dinic:
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct line
{
int s,t;
int f;
int next;
}a[100001];
int head[1001];
int edge;
int map[1001][1001];
inline void add(int s,int t,int f)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
a[edge].f=f;
}
int n;
int p;
int q[100001];
bool v[1001];
int dep[1001];
inline bool bfs(int d)
{
memset(v,false,sizeof(v));
memset(dep,-1,sizeof(dep));
int l=1,r=0;
r++;
q[r]=d;
dep[d]=0;
v[d]=true;
while(l<=r)
{
d=q[l];
int i;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(a[i].f>0&&!v[t])
{
dep[t]=dep[d]+1;
v[t]=true;
r++;
q[r]=t;
}
}
l++;
}
return v[p];
}
inline int dfs(int d,int s)
{
if(d==p)
return s;
int i;
int ts=s;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(dep[t]==dep[d]+1&&a[i].f>0)
{
int xt=dfs(t,min(s,a[i].f));
s-=xt;
a[i].f-=xt;
if(i%2==1)
a[i+1].f+=xt;
if(i%2==0)
a[i-1].f+=xt;
}
}
return ts-s;
}
inline int dinic()
{
int s=0;
while(bfs(0))
s+=dfs(0,2100000000);
return s;
}
int main()
{
int m;
scanf("%d%d",&n,&m);
int i,s,t;
for(i=1;i<=m;i++)
{
scanf("%d%d",&s,&t);
map[s][t]=1;
}
int j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][k]==1&&map[k][j]==1)
map[i][j]=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)
continue;
if(map[i][j]==1)
{
edge++;
add(i,j+n,1);
edge++;
add(j+n,i,0);
}
}
}
p=n*2+1;
for(i=1;i<=n;i++)
{
edge++;
add(0,i,1);
edge++;
add(i,0,0);
}
for(i=1;i<=n;i++)
{
edge++;
add(i+n,p,1);
edge++;
add(p,i+n,0);
}
printf("%d\n",n-dinic());
return 0;
}
hungray:
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
struct line
{
int s,t;
int next;
}a[100001];
int head[1001];
int edge;
inline void add(int s,int t)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
}
int n;
bool v[1001];
int lk[1001];
int map[201][201];
inline bool find(int d)
{
int i;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(!v[t])
{
v[t]=true;
if(lk[t]==0)
{
lk[t]=d;
return true;
}
else if(find(lk[t]))
{
lk[t]=d;
return true;
}
}
}
return false;
}
int ans;
inline void hungary()
{
int i;
for(i=1;i<=n;i++)
{
memset(v,false,sizeof(v));
if(find(i))
ans++;
}
}
int main()
{
int m;
scanf("%d%d",&n,&m);
int i,s,t;
for(i=1;i<=m;i++)
{
scanf("%d%d",&s,&t);
map[s][t]=1;
}
int j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][k]==1&&map[k][j]==1)
map[i][j]=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)
continue;
if(map[i][j]==1)
{
edge++;
add(i,j+n);
}
}
}
hungary();
printf("%d\n",n-ans);
return 0;
}