标签:最大流 acm dinic 筛选最短路的边 hdu5294
Description
Input
Output
Sample Input
8 9 1 2 2 2 3 2 2 4 1 3 5 3 4 5 4 5 8 1 1 6 2 6 7 5 7 8 1
Sample Output
2 6
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<deque>
#include<vector>
#include<utility>
using namespace std;
const int MAXN = 2510;
const int MAXM = 300010;
const int INF = 0x3f3f3f3f;
struct Edge
{
int from, to, cap, next;
};
Edge edge[MAXM];
Edge edge2[MAXM];
int head[MAXN];
int head2[MAXN];
int level[MAXN];
int dis1[MAXN], dis2[MAXN];
int src, des, cnt, cnt2;
void SPFA(int *dis, int src,int n)
{
int inqueue[MAXN] = {0};
deque<int> q;
dis[src] = 0;
inqueue[src] = 1;
q.push_front( src );
while(!q.empty())
{
int u = q.front();
q.pop_front();
for(int i = head2[u]; i !=-1;i=edge2[i].next )
{
int v = edge2[i].to;
if(dis[v]>dis[u]+edge2[i].cap)
{
dis[v] = dis[u] + edge2[i].cap;
if(!inqueue[v])
{
if(!q.empty() && dis[v] > dis[q.front()])
q.push_front( v );
else
q.push_back( v );
}
}
}
}
}
void addedge( int from, int to, int cap )
{
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].cap = cap;
edge[cnt].next = head[from];
head[from] = cnt++;
swap( from, to );
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].cap = 0;
edge[cnt].next = head[from];
head[from] = cnt++;
}
void addedge2( int from, int to, int cap )
{
edge2[cnt2].from = from;
edge2[cnt2].to = to;
edge2[cnt2].cap = cap;
edge2[cnt2].next = head2[from];
head2[from] = cnt2++;
}
bool bfs()
{
memset( level, -1, sizeof level );
queue<int> q;
while(!q.empty())
q.pop();
level[src] = 0;
q.push( src );
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > 0 && level[v] == -1)
{
level[v] = level[u] + 1;
q.push( v );
if(v == des) return level[des] != -1;
}
}
}
return level[des] != -1;
}
int dfs( int u, int f )
{
if(u == des) return f;
int tem;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > 0 && level[v] == level[u] + 1)
{
tem = dfs( v, min( f, edge[i].cap ) );
if(tem > 0)
{
edge[i].cap -= tem;
edge[i ^ 1].cap += tem;
return tem;
}
}
}
level[u] = -1;
return 0;
}
int Dinic()
{
int ans = 0, tem = 0;
while(bfs())
{
tem = dfs( src, INF );
if(tem > 0)
ans += tem;
}
return ans;
}
int main()
{
int n, m;
while(cin >> n >> m)
{
cnt = cnt2 = 0;
src = 1; des = n;
memset( head, -1, sizeof head );
memset( head2, -1, sizeof head2 );
memset( dis1, INF, sizeof dis1 );
memset( dis2, INF, sizeof dis2 );
int a, b, c;
for(int i = 1; i <= m; i++)
{
scanf( "%d%d%d",&a,&b,&c);
addedge2( a, b, c );
addedge2( b, a, c );
}
SPFA( dis1, 1, n );
SPFA( dis2, n, n );
for(int i = 1; i <= n; i++) //重构图
{
for(int j = head2[i]; j != -1; j = edge2[j].next)
{
int v = edge2[j].to;
if(dis1[i] + edge2[j].cap + dis2[v] == dis1[n])
{
addedge( i, v, 1 );
edge2[j].cap = 1;
}
else
{
edge2[j].cap = INF;
}
}
}
memset( dis1, INF, sizeof dis1 );
SPFA(dis1, 1, n );
cout << Dinic()<<" " << m-dis1[n]<<endl;
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:最大流 acm dinic 筛选最短路的边 hdu5294
原文地址:http://blog.csdn.net/maxichu/article/details/47699869