您的位置:首页 > 理论基础 > 计算机网络

【网络流】HDU 4309

2014-12-13 21:53 106 查看
平时训练题,网络流的性质还是比较明显。对于细节的处理稍微有些注意的地方。把隧道中间拆个中间点,连接到汇点,之后发现其实就用隧道u连接就够了。对于古桥修建通过子集枚举,做最大流就行了。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXN 200
#define MAXM 1000
#define MAXB 20
const int INF = 1e8;
struct node{
int v,c,f;
node *next,*back;
}*adj[MAXN * 2];
node edge[MAXM * 4];
node tedge[MAXM * 4];
node *ecnt = &edge[0];
int d[MAXN + 10],vi[MAXN + 10];
int st,ed,n,m,maxn,ansa,ansb,cnt;
int cost[MAXB  +10];
node *Pos[MAXB +10];
void addedge(int u,int v,int wt)
{
node *p = ++ecnt;
p->v = v;    p->c = wt;   p ->f = 0;
p->next = adj[u];
p->back = p + 1;
adj[u] = p;

p = ++ecnt;
p->v = u;    p->c = 0;   p ->f = 0;
p->next = adj[v];
p->back = p - 1;
adj[v] = p;
}
int aug(int i,int maxt)
{
int t = 0,mind = maxn - 1,u;
if(i == ed)
return maxt;
for(node *p = adj[i];p;p = p->next)
{
int v = p->v;
if(p->c > p->f)
{
if(d[i] == d[v] + 1)
{
u = min(maxt - t,p->c - p->f);
u = aug(v,u);
p->f += u;
p->back->f -= u;
t += u;
if(d[st] >= maxn)
return t;
if(t == maxt)
break;
}
mind = min(mind,d[v]);
}
}
if(t == 0)
{
vi[d[i]]--;
if(!vi[d[i]])
d[st] = maxn;
d[i] = mind + 1;
vi[d[i]]++;
}
return t;
}
int isap()
{
int ans = 0;
while(d[st] < maxn)
ans += aug(st,INF);
return ans;
}
void rebuild()
{
for(int i = 0;i < (1<<cnt);i++)
{
memcpy(edge,tedge, sizeof(edge));
memset(d,0,sizeof(d));
memset(vi,0,sizeof(vi));
int sum = 0;
for(int j = 0;j < cnt;j++)
if(i & (1<<j))
{
Pos[j]->c = INF;
sum += cost[j];
}
int k = isap();
if(k > ansa){
ansa = k;
ansb = sum;
}
else if(k == ansa)
ansb = min(ansb,sum);
}
}
int main()
{
int i,u,v,w,p,id = 0;
while(scanf("%d%d",&n,&m) == 2){
st = 0;
ed = n + 1;
maxn = n + 2;
cnt = ansa = ansb = 0;
memset(adj,0,sizeof(adj));
ecnt = edge;
for(i = 1;i <= n;i++){
scanf("%d",&u);
addedge(st,i,u);
}
for(i = 1;i <= m;i++){
scanf("%d%d%d%d",&u,&v,&w,&p);
if(p < 0)
{
id++;
addedge(u,v,INF);
addedge(u,ed,w);
}
else if(p == 0)
addedge(u,v,INF);
else{
Pos[cnt] = ecnt + 1;
cost[cnt++] = w;
addedge(u,v,1);
}
}
memcpy(tedge,edge, sizeof(tedge));
rebuild();
if(ansa > 0)
printf("%d %d\n",ansa,ansb);
else
printf("Poor Heaven Empire\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: