您的位置:首页 > 其它

模拟赛 花园的守护之神(时间限制:1s;空间限制:256MB)

2014-10-28 12:52 417 查看

题目描述

看着正在被上古神兽们摧残的花园,花园的守护之神――小Bug同学泪流满面。然而,FZOI不相信眼泪,小bug与神兽们的战争将进行到底!

通过google,小Bug得知,神兽们来自遥远的戈壁。为了扭转战局,小Bug决定拖延神兽增援的速度。从戈壁到达花园的路径错综复杂,由若干段双向的小路组成。神兽们通过每段小路都需要一段时间。小Bug可以通过向其中的一些小路投掷小xie来拖延神兽。她可以向任意小路投掷小Xie,而且可以在同一段小路上投掷多只小xie。每只小Xie可以拖延神兽一个单位的时间。即神兽通过整段路程的总时间,等于没有小xie时他们通过同样路径的时间加上路上经过的所有小路上的小xie数目总和。

神兽们是很聪明的。他们会在出发前侦查到每一段小路上的小Xie数目,然后选择总时间最短的路径。小Bug现在很想知道最少需要多少只小Xie,才能使得神兽从戈壁来到花园的时间变长。作为花园中可爱的花朵,你能帮助她吗?

输入格式

第1行包括一个整数N,表示地图中路点的个数;一个整数M,表示小路个数;以及整数S和T,分别表示戈壁和花园的路点编号。N个路点分别被编号为自然数1~N。

以下M行,每行三个整数A、B和C,表示路点A和B之间有一条小路相连,且通过它需要的时间为C。

输入数据保证两路点间最多只有一条小路相连,且戈壁和花园的路点是连通的。

输出格式

一个整数,表示使S到T之间最短路增长所需要的最少的小xie的数目。

输入样例

5 5 1 5

1 2 1

2 3 3

1 4 2

4 3 2

5 1 1

输出样例

1

数据范围

对于30%的数据,满足N≤10,M≤50。

对于50%的数据,满足N≤200,M≤10000。

对于全部的数据,满足N≤1000,M≤499500,0<C≤1000000。

题解

虽然我不懂为什么noip模拟赛会考到最小割,不过幸好还是A了。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#define inf 1e15
#define ll long long
using namespace std;
int n,m,S,T,hd[1002],ct;
struct bian{int to,nx; ll v;} E[999002];
//---------------------------------------
ll dis[1002];
struct dui{int w; ll d;} q[20002];
int pd[1002],size,from[1002][1002];
//----------------------------------------
int head[1002],zz=1,dui[1002],h[1002],in[1002];
ll ans;
struct liu{int to,nx,v;} e[999002];
//--------------------------------------------------------------------------
void insert1(int x,int y,ll z)
{
ct++; E[ct].to=y; E[ct].v=z; E[ct].nx=hd[x]; hd[x]=ct;
ct++; E[ct].to=x; E[ct].v=z; E[ct].nx=hd[y]; hd[y]=ct;
}
void init()
{
scanf("%d%d%d%d",&n,&m,&S,&T);
int i,x,y; ll z;
for(i=1;i<=m;i++)
{scanf("%d%d%I64d",&x,&y,&z);
insert1(x,y,z);
}
}
void heapfy(int x)
{
int l=x<<1,r=l+1,minx=x;
if(l<=size&&q[l].d<q[x].d) minx=l;
if(r<=size&&q[r].d<q[minx].d) minx=r;
if(minx!=x)
{swap(q[minx],q[x]); heapfy(minx);}
}
void del()
{
q[1]=q[size]; size--;
if(size) heapfy(1);
}
void weih(int x)
{
if(x<=1) return ;
int i=x>>1;
if(q[i].d>q[x].d) swap(q[i],q[x]);
weih(i);
}
void dijkstra()
{
int i,x,p;
for(i=1;i<=n;i++) dis[i]=inf;
size=1; q[1].w=S; q[1].d=dis[S]=0;
while(size)
{x=q[1].w; del();
if(pd[x]) continue;
pd[x]=1;
for(i=hd[x];i;i=E[i].nx)
{p=E[i].to;
if(dis[p]>dis[x]+E[i].v)
{dis[p]=dis[x]+E[i].v;
from[p][0]=1; from[p][from[p][0]]=x;
size++; q[size].w=p; q[size].d=dis[p]; weih(size);
}
else if(dis[p]==dis[x]+E[i].v)
{from[p][0]++; from[p][from[p][0]]=x;}
}
}
}
//------------------------------------------------------------------------------
void insert2(int x,int y)
{
zz++; e[zz].to=y; e[zz].v=1; e[zz].nx=head[x]; head[x]=zz;
zz++; e[zz].to=x; e[zz].v=0; e[zz].nx=head[y]; head[y]=zz;
}
void rebuild()
{
int i,j,t=0,w=1;
dui[t]=T; in[T]=1;
while(t<w)
{i=dui[t]; t++;
for(j=1;j<=from[i][0];j++)
{if(!in[from[i][j]]) {dui[w]=from[i][j]; in[from[i][j]]=1; w++;}
insert2(from[i][j],i);
}
}
}
bool bfs()
{
int t=0,w=1,x,i,p;
memset(h,-1,sizeof(h));
dui[0]=S; h[S]=0;
while(t!=w)
{x=dui[t]; t=(t+1)%n;
for(i=head[x];i;i=e[i].nx)
{p=e[i].to;
if(h[p]<0&&e[i].v)
{h[p]=h[x]+1;
dui[w]=p; w=(w+1)%n;
}
}
}
if(h[T]<0) return false;
else return true;
}
int dfs(int x,int f)
{
if(x==T) return f;
int i,rest,usd=0,p;
for(i=head[x];i;i=e[i].nx)
{p=e[i].to;
if(h[p]==h[x]+1&&e[i].v)
{rest=f-usd;
rest=dfs(p,min(e[i].v,rest));
e[i].v-=rest;
e[i^1].v+=rest;
usd+=rest;
if(usd==f) return f;
}
}
if(!usd) h[x]=-1;
return usd;
}
void dinic()
{
while(bfs()) ans+=dfs(S,0x7fffffff);
printf("%I64d\n",ans);
}
int main()
{
freopen("greendam.in","r",stdin);
freopen("greendam.out","w",stdout);
init(); dijkstra();
rebuild(); dinic();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最小割