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

BZOJ 3931: [CQOI2015]网络吞吐量【最短路+网络流

2016-09-18 19:41 357 查看
裸的最短路+乱搞+拆点+网络流

……忘了拆点会点数<<1,于是数组开小了又WA又T了一年【跪地不起我………………

反正点的流量限制就把它拆成入点和出点两个,中间加一条边就好了

找所有最短路直接for边就好……

…………拆点…………注意………………数组…………开大…………………………

裸题T了一年……果然我是要退役了QAQ

#include<bits/stdc++.h>
//#define Flaze_naive
#define MAXN 1515
#define MAXM 100057
#define INF 1000000000000000000ll
using namespace std;	int n,m;
int read_x[MAXM],read_y[MAXM],read_l[MAXM];
int S=0,T;
long long dis[MAXN];
int in_que[MAXN],que[MAXN],head,tail;
long long ans=0;

void addedge(int x,int y,long long liu);

struct t1{
int to,lth;
t1(){}
t1(int to,int lth):to(to),lth(lth){}
};
vector<t1> e[MAXN];

void SPFA(int now){
memset(dis,0x3f3f3f3f,sizeof dis);
head=tail=0;
que[tail++]=now;
in_que[now]=1;
dis[now]=0;
while(head^tail){
now=que[head++];
if(head==MAXN)	head=0;
in_que[now]=0;
for(int tmp=0;tmp<e[now].size();++tmp){
int aim=e[now][tmp].to;
if(dis[aim]>dis[now]+e[now][tmp].lth){
dis[aim]=dis[now]+e[now][tmp].lth;
if(!in_que[aim])	que[tail++]=aim,in_que[aim]=1;
if(tail==MAXN)	tail=0;
}
}
}
}

int c[MAXN];
int iin[MAXN],ott[MAXN];
int cnt_node=0;
void build(int now){
iin[1]=ott[1]=++cnt_node,iin
=ott
=++cnt_node;
for(int i=2;i<n;++i)
iin[i]=++cnt_node,ott[i]=++cnt_node,
addedge(iin[i],ott[i],c[i]);
T=++cnt_node;
addedge(S,iin[1],INF),addedge(ott
,T,INF);

for(int i=1;i<=m;++i){
if(dis[read_x[i]]==dis[read_y[i]]+read_l[i])
addedge(ott[read_y[i]],iin[read_x[i]],INF);
if(dis[read_x[i]]+read_l[i]==dis[read_y[i]])
addedge(ott[read_x[i]],iin[read_y[i]],INF);
}
}
//=======================================================================================
struct edge_for_dinic{
int to,nxt;
long long liu;
int tag;
edge_for_dinic(){}
edge_for_dinic(int to,int nxt,long long liu):to(to),nxt(nxt),liu(liu){}
}edge[MAXM<<2];	int cnt_edge=1;
int fst[MAXN<<1],cur[MAXN<<1];

void addedge(int x,int y,long long liu){
edge[++cnt_edge]=edge_for_dinic(y,fst[x],liu);
fst[x]=cnt_edge;
edge[++cnt_edge]=edge_for_dinic(x,fst[y],0);
fst[y]=cnt_edge;
}

long long dfs(int now,long long low){
if(now==T)	return low;
long long rst=low;
for(int &tmp=cur[now];tmp;tmp=edge[tmp].nxt){
if(dis[now]+1!=dis[edge[tmp].to]||edge[tmp].liu<=0)	continue;
int aim=edge[tmp].to;
long long tt=dfs(aim,min(rst,edge[tmp].liu));
if(tt){
edge[tmp].liu-=tt;
edge[tmp^1].liu+=tt;
rst-=tt;
if(!rst)	return low;
}
}
if(low==rst)	dis[now]=-1;
return low-rst;
}

bool bfs(int now){
memset(dis,-1,sizeof dis);
head=tail=0;
que[tail++]=now;
dis[now]=0;
for(int i=S;i<=cnt_node;++i)	cur[i]=fst[i];
cur[T]=fst[T];
while(head^tail){
now=que[head++];
if(head==MAXN)	head=0;
for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
int aim=edge[tmp].to;
if(dis[aim]!=-1||edge[tmp].liu<=0)	continue;
dis[aim]=dis[now]+1;
que[tail++]=aim;
if(tail==MAXN)	tail=0;
}
}
return ~dis[T];
}

void dinic(){
long long tt;
while(bfs(S)){
while(tt=dfs(S,INF))
ans+=tt;
}
}

//=======================================================================================

int main(){
#ifdef Flaze_naive
freopen("1.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
scanf("%d%d%d",&read_x[i],&read_y[i],&read_l[i]);
if(read_x[i]==read_y[i])	continue;
e[read_x[i]].push_back(t1(read_y[i],read_l[i]));
e[read_y[i]].push_back(t1(read_x[i],read_l[i]));
}
SPFA(1);
for(int i=1;i<=n;++i)	scanf("%d",c+i);
build(n);
dinic();
printf("%lld",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: