模拟赛 花园的守护之神(时间限制: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 51 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; }
相关文章推荐
- 模拟赛 数字(时间限制:1s;空间限制:128MB)
- 模拟赛 弱点(时间限制:2S;空间限制:256MB)
- 模拟赛 滑动的窗户(时间限制:3s;空间限制256MB)
- 模拟赛 球的序列(时间限制1s,内存限制256MB)
- 模拟赛 计算(时间限制:1s;空间限制 64MB)
- 模拟题 宠物之战(时间限制:1s;空间限制:256MB)
- 模拟赛 改造二叉树(时间限制 1s;空间限制 256M)
- 模拟赛 字符串(时间限制:1s;空间限制:256MB)
- 模拟赛 密室逃脱(时间限制:1s;空间限制:256MB)
- 模拟赛 感冒病毒(时间限制:1s;空间限制:256MB)
- 模拟赛 狐狸的谜语(时间限制:1s,空间限制:128MB)
- 模拟赛 序列问题(时间限制:1s;空间限制:128MB)
- 模拟赛 祖孙询问(时间限制:1s;空间限制:128MB)
- 模拟赛 最大公约数(时间限制:1s,空间限制:128MB)
- 模拟赛 买汽水(时间限制:2s,空间限制:128MB)
- 模拟赛 长途旅行(时间限制:1s;空间限制:256M)
- 模拟赛 藏宝图(时间限制:2s,空间限制:256MB)
- 模拟赛 Incr(时间限制:1s;空间限制:128MB)
- 模拟赛 数列(时间限制 1s;内存限制:128MB)
- 模拟赛 数位和乘积(时间限制 1000MS,内存限制 256MB)