| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
哪位大侠进来看看,为什么呀!计算最大流我用dinic就AC 但是用距离标号就WA都同样是计算最大流 为什么ISAP不行呢?
难道是算法有错,可做其他最大流两个都可以过呀 这。。。下面提供的那个长数据用我得ISAP确实是过不了 结果是26 但dinic能过 不知道哪里错了 望大侠指点。。。。拜谢了
#include <iostream>
#include <cstring>
using namespace std;
#define MIN(x,y) ((x)<(y)?(x):(y))
const int MAXN = 403;
const int INF = 123456789;
int N,F,D;
int start,end;
int flow[MAXN][MAXN];
int id[MAXN];
int num[MAXN];
int pre[MAXN];
int init()
{
if(scanf("%d%d%d",&N,&F,&D)!=3)return 0;
int i,k,k1;
int t;
memset(flow, 0 ,sizeof(flow));
for(i=1;i<=N;++i)
{
scanf("%d%d",&k,&k1);
while(k--)
{
scanf("%d",&t);
flow[t][i+F]=1; //t--i+F t为食物 i+f为牛 容量为1
}
flow[F+i][F+N+i]=1;
while(k1--)
{
scanf("%d",&t);
flow[F+N+i][2*N+F+t] = 1 ;//f+i --2*N+F+t 前为牛 后为水 容量为1
}
}
for(i=1;i<=F;++i) flow[0][i]=1;
for(i=2*N+F+1;i<=2*N+F+D;++i) flow[i][2*N+F+D+1]=1;
start=0;
end=2*N+F+D+1;
return 1;
}
int bfs(int s) //得到各个节点的层次
{
int i,k,front=0,rear=0;
int q[MAXN];
memset( id , -1 , sizeof( id ));
q[rear++]=s;id[s]=0;
while( front < rear )
{
k = q[ front ++ ];
for ( i = 0 ; i <= end ; ++ i )
if( flow[ k ][ i] > 0 && id[ i ] == -1 )
{
q[ rear ++ ] = i ;
id[ i ] =id[ k ] + 1 ;
}
}
return id[ end ] != -1 ;
}
int dinic(int s,int max) //求最大流
{
int t,i;
int now = max ;
if( s == end ) return max ;
for( i = 0 ; i <= end ; ++ i)
{
if(flow[ s ][ i ] > 0 && id[ i ] == id[ s ] + 1 )
{
t = dinic( i , MIN(flow[s][i] , max ) );
flow[s][i] -= t;
flow[i][s] += t;
max -= t;
}
}
return now - max;
}
int bfs2(int t) //反向bfs计算距离标号
{
int q[MAXN];
int f=0,r=0;
int k,i;
memset(id,-1,sizeof(id));
memset(num,0,sizeof(num));
q[r++]=t;id[t]=0;
while(f<r)
{
k=q[f++];
for(i=0;i<=end;i++)
{
if(flow[i][k]>0&&id[i]==-1)
{
id[i]=id[k]+1;
q[r++]=i;
num[id[i]]++;
}
}
}
return 1;
}
int find(int t) //查找可行狐
{
int i;
for(i=1;i<=end;++i)
{
if(flow[t][i]>0 && id[t]==id[i]+1) return i;
}
return -1;
}
int relabel(int t) //重新标号
{
int i;
int mm = end+2;
for(i=0;i<=end;++i)
{
if(flow[t][i]>0) mm = MIN(mm,id[i]+1);
}
return mm;
}
int maxFlow()
{
int sumflow = 0;
int nowflow;
int i=start; //初始化为源点
int j;
memset(pre,-1,sizeof(pre));
while(id[start]<end+1)
{
j =find(i);
if(j>=0)
{
pre[j] = i;
i = j;
if(i==end) //找到了一条增广路径
{
nowflow = INF;
for(i=end;i!=start;i=pre[i])
nowflow=MIN(nowflow,flow[pre[i]][i]); //求的增广路径的可增流量
for(i=end;i!=start;i=pre[i])
flow[pre[i]][i]-= nowflow, flow[i][pre[i]] += nowflow; //修改残留网络
sumflow += nowflow;
}
}
else //可行狐不存在
{
int x = relabel(i); //重新计算距离标号
num[x]++;
num[id[i]]--;
if(num[id[i]]==0) return sumflow; //优化 如果出现距离标号断了的情况 则说明不可能存在增广路了 直接返回流量
id[i] = x;
if(i!=start) i =pre[i]; //回退 当i不为源点时回退
}
}
return sumflow;
}
int main()
{
freopen( "in.txt" , "r" , stdin );
// while(
init();//)
//{
// int max=0;
// while(bfs(start))max+=dinic(start,INF);
// printf("%d\n",max);
bfs2(end);
printf("%d\n",maxFlow());
//}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator