您的位置:首页 > 其它

hdu 4280 Island Transport 最大流dinic算法

2012-09-11 23:10 417 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4280

题意:

给定平面上n个点的坐标,最左边的点为源点,最右边的点为汇点,给出m条边的容量求最大流。

思路:

才开始理解错了题意,For safety, no two routes are cross or overlap and no routes will pass an island except the departing island and the arriving island。以为要处理线段不能相交什么的,不知道怎么做了。原来直接见图套模板即可,题目保证不会相交。为此我和von纠结了好久。。

View Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>

#define CL(a,num) memset((a),(num),sizeof(a))
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define Min(a,b) (a) > (b)? (b):(a)
#define Max(a,b) (a) > (b)? (a):(b)

#define ll long long
#define inf 0x7f7f7f7f
#define MOD 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("<------------------->")
#define maxn 100007
#define M 100007
#define N 100007
using namespace std;
//freopen("din.txt","r",stdin);

struct point{
int x,y;
int id;
}p
;

struct node{
int v,w;
int next;
}g[M*4 + 10];

int head
,ct;
int level
,q[N*100];
int n,m;

void init(){
ct = 0;
CL(head,-1);
}
void add(int u,int v,int w){
g[ct].v = v;
g[ct].w = w;
g[ct].next = head[u];
head[u] = ct++;

g[ct].v = u;
g[ct].w = 0;
g[ct].next = head[v];
head[v] = ct++;
}
int cmp(point a,point b){
return a.x < b.x;
}
bool layer(int s,int e){
int i;
CL(level,-1);
level[s] = 0;
int l,r;
l = r = 0;
q[r] = s;
while (l <= r){
int u = q[l++];
for (i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if (level[v] == -1 && g[i].w > 0){
level[v] = level[u] + 1;
q[++r] = v;
if (v == e) return true;
}
}
}
return false;
}
int find(int s,int e){
int i;
int ans = 0;
int top = 1;

while (top){
int u = (top == 1 ? s : g[q[top - 1]].v);

if (u == e){
int MIN = inf,pos;
for (i = 1; i < top; ++i){
int tp = q[i];
if (g[tp].w < MIN){
MIN = g[tp].w;
pos = i;
}
}
for (i = 1; i < top; ++i){
int tp = q[i];
g[tp].w -= MIN;
g[tp^1].w += MIN;
}
ans += MIN;
top = pos;
}
else{
for (i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if (g[i].w > 0 && level[v] == level[u] + 1){
q[top++] = i;
break;
}
}
if (i == -1){
top--;
level[u] = -1;
}
}
}
return ans;
}
int Dinic(int s,int e){
int ans = 0;
while (layer(s,e)) ans += find(s,e);
return ans;
}
int main(){
//freopen("din.txt","r",stdin);
int t,i;
int x,y,z;
scanf("%d",&t);
while (t--){
init();
scanf("%d%d",&n,&m);
for (i = 0; i < n; ++i){
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id = i + 1;
}
//建图
for (i = 0; i < m; ++i){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
//排序,找源点汇点
sort(p,p + n,cmp);
int s = p[0].id,e = p[n - 1].id;

printf("%d\n",Dinic(s,e));//模板
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: