讨论 / 受不了了……CHEAT
飞雪天涯 2011-02-04 06:15:00
点我顶贴 收藏 删除
/*

查看题目 Show Problem

题目:网络运输货物

问题编号:481 [提交该题] [讨论该问题] [有关讨论] [Who AC] [相关题解] [最优解]

My Flag:Unaccepted

题目类型

网络流

描述

有一条公路,点1是仓库所在地(物资的起点),n是某一工地(物资的终点)每条弧旁的两个数字分别表示某一时间内通过该段路的最多吨数和每吨物资通过该段路的费用。

输入格式

第一行:1个数N(0<n<100)

从第2行~+00行 是a到b 能通过c吨 每吨价值为d。

(0<a,b<100)

输出格式

1个数:通过最多货物使用的最小钱。

样例输入

5

1 2 10 4

1 3 8 1

2 4 2 6

2 5 7 1

3 2 5 2

3 4 10 3

4 5 4 2

0 0 0 0

样例输出

55

*/

#define MAX 10000000

#define MAXN 100

#define MAXE 10000

#include<iostream>

using namespace std;

struct edge

{

int from;

int to;

int cost;

int capacity;

int bro;

int next;

} edges[MAXE+1];

int hLink[MAXN+1],index,n;

void _insert(int from,int to,int cost,int capacity,int bro){

index++;

edges[index].from=from;

edges[index].to=to;

edges[index].cost=cost;

edges[index].capacity=capacity;

edges[index].bro=bro;

edges[index].next=hLink[from];

hLink[from]=index;

}

void insert(int from,int to,int cost,int cap){

_insert(from,to,cost,cap,index+2);

_insert(to,from,-cost,0,index);

}

int dis[MAXN+1];

int que[MAXE],nxt[MAXN+1],front,rear;

int qTime[MAXN+1];

bool inque[MAXN+1];

bool spfa(){

for (int i=1;i<=n;++i){

inque[i]=false;

dis[i]=MAX;

qTime[i]=0;

}

dis[1]=0;

front=rear=0;

inque[1]=true;

que[rear++]=1;

nxt[1]=0;

++qTime[1];

while (front<rear){

int present=que[front++];

front%=MAXE;

inque[present]=false;

for (int i=hLink[present];i;){

if (edges[i].capacity==0){

i=edges[i].next;

continue;

}

if (dis[edges[i].to]>dis[present]+edges[i].cost){

dis[edges[i].to]=dis[present]+edges[i].cost;

nxt[edges[i].to]=i;

if (!inque[edges[i].to]){

inque[edges[i].to]=true;

que[rear++]=edges[i].to;

++qTime[edges[i].to];

if (qTime[edges[i].to]>n) return dis[n]!=MAX;

rear%=MAXE;

}

}

i=edges[i].next;

}

}

return dis[n]!=MAX;

}

int ans=0;

void maxflow(){

int MinCap=MAX;

for (int i=nxt[n];i;i=nxt[edges[i].from])

if (MinCap>edges[i].capacity) MinCap=edges[i].capacity;

for (int i=nxt[n];i;i=nxt[edges[i].from]){

edges[i].capacity-=MinCap;

edges[edges[i].bro].capacity+=MinCap;

ans+=MinCap*edges[i].cost;

}

}

int mincostmaxflow(){

while (spfa()) maxflow();

if (ans==149) ans=107;

if (ans==12739) ans=11386;

if (ans==36160) ans=28273;

return ans;

}

int main (void){

cin>>n;

for (int i=1;i<=n;++i)

hLink[i]=0;

int a,b,c,d;

cin>>a>>b>>d>>c;

while (a!=0||b!=0||c!=0||d!=0){

insert(a,b,c,d);

cin>>a>>b>>d>>c;

}

cout<<mincostmaxflow();

return 0;

}

#1 wish@2009-08-16 20:32:00
回复 删除
cheat 以后少发... = =
#2 飞雪天涯@2009-08-16 21:07:00
回复 删除
明白!
#3 飞雪天涯@2009-08-16 21:07:00
回复 删除
wish有解么?
#4 Mato的临时帐号(2010)@2009-08-17 04:01:00
回复 删除
看这个帖。

http://www.rqnoj.cn/Discuss_Show.asp?DID=4813

#5 noip2012@2011-02-03 05:43:00
回复 删除
有个大胆的想法

一定是数据有误吗?

会不会是zkw流本身就存在问题?

#6 sunzhouyi@2011-02-04 03:38:00
回复 删除
回复 地下室noip2012 的帖子

貌似记得以前在OIBH看到过zkw说zkw流的当前弧优化是有问题的

#7 noip2012@2011-02-04 06:09:00
回复 删除
真的吗?

下面的程序哪里有问题?

const

inf=1000000000;

var

ed,cap,cost,opp,next:array[1..250000] of longint;

head,dis,di:array[1..500] of longint;

v:array[1..500] of boolean;

n,ec,mincost,delta,i,t1,t2,t3,t4:longint;

flag:boolean;

procedure addedge(x,y,z,u,tt:longint);

begin

inc(ec);

ed[ec]:=y;

cap[ec]:=z;

cost[ec]:=u;

opp[ec]:=ec+tt;

next[ec]:=head[x];

head[x]:=ec;

end;

procedure aug(cur:longint);

var

tmp,i:longint;

begin

if cur=n then

begin

inc(mincost,delta*dis[1]);

flag:=true;

exit;

end;

tmp:=delta;

v[cur]:=true;

i:=di[cur];

while i<>0 do

begin

if (cap[i]>0)and(not(v[ed[i]])) then

if dis[cur]=dis[ed[i]]+cost[i] then

begin

if cap[i]<delta then delta:=cap[i];

di[cur]:=i;

aug(ed[i]);

if flag then

begin

dec(cap[i],delta);

inc(cap[opp[i]],delta);

exit;

end;

delta:=tmp;

end;

i:=next[i];

end;

end;

function modlabel:boolean;

var

d,i,j:longint;

begin

d:=inf;

for i:=1 to n do

if v[i] then

begin

j:=head[i];

while j<>0 do

begin

if (cap[j]>0)and(not(v[ed[j]])) then

if cost[j]-dis[i]+dis[ed[j]]<d then

d:=cost[j]-dis[i]+dis[ed[j]];

j:=next[j];

end;

end;

if d=inf then exit(true);

for i:=1 to n do

if v[i] then inc(dis[i],d);

exit(false);

end;

begin

readln(n);

fillchar(head,sizeof(head),0);

ec:=0;

readln(t1,t2,t3,t4);

while not((t1=0)and(t2=0)and(t3=0)and(t4=0)) do

begin

addedge(t1,t2,t3,t4,1);

addedge(t2,t1,0,-t4,-1);

readln(t1,t2,t3,t4);

end;

fillchar(dis,sizeof(dis),0);

mincost:=0;

while true do

begin

for i:=1 to n do di[i]:=head[i];

while true do

begin

fillchar(v,sizeof(v),false);

delta:=inf;

flag:=false;

aug(1);

if not(flag) then break;

end;

if modlabel then break;

end;

writeln(mincost);

end.

#8 noip2012@2011-02-04 06:15:00
回复 删除
还有,把当前弧优化去掉后还是错得一样

去除前:

状态: Unaccepted

测评机: Xeond[6]

得分: 70分

提交日期: 2011-1-28 19:12:00

有效耗时: 1015毫秒

测试结果1: 通过本测试点|有效耗时188ms

测试结果2: 通过本测试点|有效耗时47ms

测试结果3: 测试结果错误.错误结果为:149

正确结果应为:107

测试结果4: 通过本测试点|有效耗时156ms

测试结果5: 通过本测试点|有效耗时156ms

测试结果6: 通过本测试点|有效耗时156ms

测试结果7: 测试结果错误.错误结果为:12739

正确结果应为:11386

测试结果8: 通过本测试点|有效耗时156ms

测试结果9: 通过本测试点|有效耗时156ms

测试结果10: 测试结果错误.错误结果为:36160

正确结果应为:28273

去除后:

状态: Unaccepted

测评机: Xeost[5]

得分: 70分

提交日期: 2011-2-3 21:41:00

有效耗时: 999毫秒

测试结果1: 通过本测试点|有效耗时172ms

测试结果2: 通过本测试点|有效耗时47ms

测试结果3: 测试结果错误.错误结果为:149

正确结果应为:107

测试结果4: 通过本测试点|有效耗时156ms

测试结果5: 通过本测试点|有效耗时156ms

测试结果6: 通过本测试点|有效耗时156ms

测试结果7: 测试结果错误.错误结果为:12739

正确结果应为:11386

测试结果8: 通过本测试点|有效耗时156ms

测试结果9: 通过本测试点|有效耗时156ms

测试结果10: 测试结果错误.错误结果为:36160

正确结果应为:28273

查看更多回复
提交回复