感觉这道题纯粹就是试模板的,给一个有向图,求其最大流
Dinic算法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define inf 300
#define lim 0x7fffffff
int flow[inf][inf];
int dis[inf];
int n,m;
int bfs()
{
int i;
memset(dis,-1,sizeof(dis));
dis[1]=0;
queue<int> que;
que.push(1);
while(que.size())
{
int now=que.front();
que.pop();
for(i=1;i<=n;i++)
{
if(flow[now][i]>0&&dis[i]<0)
{
dis[i]=dis[now]+1;
que.push(i);
}
}
}
if(dis[n]>0)
return 1;
return 0;
}
int dfs(int x,int mx)
{
int i;int a;
if(x==n)
return mx;
for(i=1;i<=n;i++)
{
if(flow[x][i]>0&&dis[i]==dis[x]+1&&(a=dfs(i,min(mx,flow[x][i]))))
{
flow[x][i]-=a;
flow[i][x]+=a;
return a;
}
}
return 0;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
int si,ei,ci;
memset(flow,0,sizeof(flow));
while(m--)
{
scanf("%d%d%d",&si,&ei,&ci);
flow[si][ei]+=ci;
}
int ans=0;
int res;
while(bfs())
{
while(res=dfs(1,lim))
ans+=res;
}
printf("%d\n",ans);
}
return 0;
}
ISAP算法:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn = 210 ;
const int inf = 0x7fffffff ;
int cur[maxn] , gap[maxn] , pre[maxn] ;
int head[maxn] , dis[maxn] ;
int st , en , nedge , n , m ;
struct Edge
{
int v , w ;
int next ;
}edge[maxn<<1] ;
void addedge(int u , int v , int w)
{
edge[nedge].v = v ;
edge[nedge].w = w ;
edge[nedge].next = head[u] ;
head[u] = nedge++ ;
edge[nedge].v = u ;
edge[nedge].w = 0;
edge[nedge].next = head[v] ;
head[v] = nedge++ ;
}
void bfs()
{
memset(dis, -1 , sizeof(dis)) ;
memset(gap , 0 , sizeof(gap)) ;
queue<int> que ;
dis[en] = 0 ; gap[0]++ ;
que.push(en) ;
while(que.size())
{
int u = que.front() ;que.pop() ;
for(int i = head[u] ; i != -1 ;i = edge[i].next)
{
int v = edge[i].v ;
if(dis[v] < 0 && edge[i^1].w > 0)
{
dis[v] = dis[u] + 1 ;
gap[dis[v]]++ ;
que.push(v) ;
}
}
}
}
int isap()
{
bfs() ;
memset(pre , -1 , sizeof(pre)) ;
memcpy(cur , head, sizeof(head)) ;
int u = pre[st] = st ;
gap[0] = n ;
int maxflow =0 ;
int aug = inf ;bool flag ;
while(dis[st] < n)
{
flag = false ;
for(int i = cur[u] ;i != -1 ;i = edge[i].next)
{
int v = edge[i].v ;
if(dis[u] == dis[v] + 1 && edge[i].w > 0)
{
flag = true ;
cur[u] = i ;
pre[v] = u ; u = v ;
aug = min(aug , edge[i].w) ;
if(v == en)
{
maxflow += aug ;
for(u = pre[v] ; ; u = pre[u])
{
edge[cur[u]].w -= aug ;
edge[cur[u]^1].w += aug ;
if(u == st)break;
}
aug = inf ;
}
break ;
}
}
if(flag)continue ;
int mi = n;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(dis[v] < mi && edge[i].w > 0)
{
mi=dis[v];
cur[u]=i;
}
}
if((--gap[dis[u]]) == 0)break ;
dis[u] = mi + 1 ;
gap[dis[u]]++ ;
u = pre[u] ;
}
return maxflow ;
}
int main()
{
//freopen("in.txt" , "r" , stdin) ;
while(~scanf("%d%d" , &m , &n))
{
memset(head, -1 , sizeof(head)) ;
nedge = 0 ;
int u , v , w ;
while(m--)
{
scanf("%d%d%d" , &u , &v , &w) ;
addedge(u ,v , w);
}
st = 1 ; en = n ;
cout<<isap()<<endl;
}
}