很基本的最大流问题,注意重边就好……
自己写了个EK模板,重边部分没有处理好,WA了好几次。
hdu 1523也是一样的题目(不过忘记杭电用I64d,poj用lld这个问题了……于是TLE了好几次……)
/****
裸最大流问题
EK算法
1004K 0MS C++ 3768B 2012-10-18 16:13:15
Ps:一开始Max = 1000 flow、lim数组开了long long的时候时间是47MS= =
ps:hdu 要用I64d......
****/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#define Begin_s 1
using namespace std;
const int Max = 410;
int path[Max];
int flow[Max][Max];
int lim[Max];
bool vis_seg[Max][Max];
bool vis[Max];
int pre[Max];
void q_clear( std::queue<int> &q )
{
std::queue<int> empty;
std::swap( q, empty );
}
struct no
{
int v;
int next;
} note[Max];
inline void init()
{
memset(vis , 0 ,sizeof(vis));
memset(path , 0 , sizeof(path));
memset(lim , 0 , sizeof(lim));
}
inline void Ford_Fulkerson(int n , int u0)/****Time:O(nmU) U:f(u,v)****/
{
bool note_break = true;
queue<int> Q;
while(note_break)
{
//update flow
int tem = n;
int add = lim[n];
while(tem != u0 && tem != 0 && lim[tem])
{
int add2 = (flow[path[tem]][tem] >= 0 ? -add : add);
flow[path[tem]][tem] += add2;
flow[tem][path[tem]] += add2;
tem = path[tem];
}
//initialize
init();
q_clear(Q);
path[u0] = u0;
lim[u0] = 2e8;
vis[u0] = 1;
Q.push(u0);
//bfs
while(!lim[n])
{
if(Q.empty() && !lim[n])
{
note_break = false;
break;
}
int u = Q.front();
Q.pop();
int p = pre[u];
while(p)
{
if(vis[note[p].v])
{
p = note[p].next;
continue;
}
if(flow[u][note[p].v] >=0)
lim[note[p].v] = min(lim[u] , flow[u][note[p].v]);
else
lim[note[p].v] = min(lim[u] , -flow[u][note[p].v]);
if(lim[note[p].v])
{
path[note[p].v] = u;
Q.push(note[p].v);
vis[note[p].v] = 1;
}
p = note[p].next;
}
}
}
}
int main()
{
// freopen("123.txt","r",stdin);
int n , m;
while(~scanf("%d %d" , &m , &n))
{
memset(note , -1 , sizeof(note));
memset(pre , 0 , sizeof(pre));
memset(flow , 0 , sizeof(flow));
memset(vis_seg , 0 , sizeof(vis_seg));
init();
//build the adjacency list
int index = 1;
for(int i = 1 ; i <= m ; i++)
{
int u , v , f;
long long c;
scanf("%d %d %d" , &u , &v , &c);
if(u == n) continue;
if(!vis_seg[u][v])
{
vis_seg[u][v] = vis_seg[v][u] = 1;
note[index].v = v;
note[index].next = pre[u];
pre[u] = index++;
note[index].v = u;
note[index].next = pre[v];
pre[v] = index++;
}
flow[u][v] += c;
// flow[v][u] = 0;
}
Ford_Fulkerson(n , Begin_s);
// for(int i = Begin_s ; i <= n ; i++)
// {
// int p = pre[i];
// while(p)
// {
// if(flow[i][note[p].v] != 0)
// printf("%d -> %d: f:%d\n" , i , note[p].v , flow[i][note[p].v]);
// p = note[p].next;
// }
// }
long long Max_flow = 0;
int p = pre[n];
while(p)
{
Max_flow += (-flow[n][note[p].v]);
p = note[p].next;
}
printf("%lld\n" , Max_flow);
}
}