这个题确实没想到可以用网络流做,不过看了Disscuss好像网络流做法并不正确,好像用DFS就可以过
参考了下别人博客:http://hi.baidu.com/buaa_babt/item/59aef80a6923d021a2332a29
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=501;
const int maxm=10000;
const int inf=1<<29;
int n,m,k,e,st,des,x[maxm],y[maxm],map[maxn][maxn],pnt[maxm],cost[maxm],nxt[maxm],head[maxn*3],level[maxn*3],q[maxn*3];
void Init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
map[i][j]=map[j][i]=inf;
map[i][i]=0;
}
}
void read()
{
Init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x[i],&y[i]);
map[x[i]][y[i]]=1;
}
}
void Floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
if(map[i][k]<inf)
for(int j=1;j<=n;j++)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}
void AddEdge(int u,int v,int c)
{
pnt[e]=v;nxt[e]=head[u];cost[e]=c;head[u]=e++;
pnt[e]=u;nxt[e]=head[v];cost[e]=0;head[v]=e++;
}
void BuildGraph()
{
e=0,st=n+1,des=n;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
if(map[1][x[i]]+map[y[i]][n]<k)
AddEdge(x[i]+n,y[i],inf);
for(int i=1;i<=n;i++)
AddEdge(i,i+n,1);
}
bool BFS()
{
memset(level,0,sizeof(level));
level[st]=1;
int pre=0,last=1;
q[pre]=st;
while(pre<last)
{
if(q[pre]==des)
return true;
for(int i=head[q[pre]];i!=-1;i=nxt[i])
if(cost[i]&&!level[pnt[i]])
{
level[pnt[i]]=level[q[pre]]+1;
q[last++]=pnt[i];
}
pre++;
}
return level[des];
}
int DFS(int u,int sum)
{
if(u==des)
return sum;
for(int i=head[u],t;i!=-1;i=nxt[i])
if(cost[i]&&level[pnt[i]]==level[u]+1&&(t=DFS(pnt[i],min(sum,cost[i]))))
{
cost[i]-=t;
cost[i^1]+=t;
return t;
}
return level[u]=0;
}
int Go()
{
int sum=0;
BuildGraph();
while(BFS())
while(1)
{
int val=DFS(st,inf);
if(!val)
break;
sum+=val;
}
return sum;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k))
{
read();
Floyd();
printf("%d\n",Go());
}
return 0;
}