[BZOJ]1266: [AHOI2006]上学路线route spfa+最小割

来源:互联网 发布:举报淘宝盗图 编辑:程序博客网 时间:2024/05/21 21:41

Description

可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校。直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的。 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上学需要的最少时间吧!” 合肥市一共设有N个公交车站,不妨将它们编号为1…N的自然数,并认为可可和卡卡家住在1号汽车站附近,而他们学校在N号汽车站。市内有M条直达汽车路线,执行第i条路线的公交车往返于站点pi和qi之间,从起点到终点需要花费的时间为ti。(1<=i<=M, 1<=pi, qi<=N) 两个人坐在电脑前,根据上面的信息很快就编程算出了最优的乘车方案。然而可可忽然有了一个鬼点子,他想趁卡卡不备,在卡卡的输入数据中删去一些路线,从而让卡卡的程序得出的答案大于实际的最短时间。而对于每一条路线i事实上都有一个代价ci:删去路线的ci越大卡卡就越容易发现这个玩笑,可可想知道什么样的删除方案可以达到他的目的而让被删除的公交车路线ci之和最小。 [任务] 编写一个程序:  从输入文件中读取合肥市公交路线的信息;  计算出实际上可可和卡卡上学需要花费的最少时间;  帮助可可设计一个方案,删除输入信息中的一些公交路线,使得删除后从家到学校需要的最少时间变大,而被删除路线的ci和最小;向输出文件输出答案。

题解:

先spfa跑出最短路,然后看哪些边是最短路上的边,建图跑最小割即可。

代码:

#include<bits/stdc++.h>using namespace std;#define LL long longconst int inf=2147483647;const int Maxn=510;const int Maxm=124760;int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}    return x*f;}struct Edge1{int y,d,c,next;}E[Maxm*2];int Last[Maxn],Len=0;void Ins(int x,int y,int d,int c){    int t=++Len;    E[t].y=y;E[t].d=d;E[t].c=c;    E[t].next=Last[x];Last[x]=t;}struct Edge{int y,d,next;}e[Maxm*2];int last[Maxn],len=1;void ins(int x,int y,int d){    int t=++len;    e[t].y=y;e[t].d=d;    e[t].next=last[x];last[x]=t;}void addedge(int x,int y,int d){ins(x,y,d);ins(y,x,0);}int n,m,f[Maxn];bool in[Maxn];queue<int>q;void spfa(){    memset(in,false,sizeof(in));    memset(f,63,sizeof(f));f[1]=0;    q.push(1);    while(!q.empty())    {        int x=q.front();q.pop();in[x]=false;        for(int i=Last[x];i;i=E[i].next)        {            int y=E[i].y;            if(f[x]+E[i].d<f[y])            {                f[y]=f[x]+E[i].d;                if(!in[y])in[y]=true,q.push(y);            }        }    }    printf("%d\n",f[n]);}int h[Maxn],st,ed;bool bfs(){    memset(h,0,sizeof(h));h[st]=1;    q.push(st);    while(!q.empty())    {        int x=q.front();q.pop();        for(int i=last[x];i;i=e[i].next)        if(e[i].d&&!h[e[i].y])h[e[i].y]=h[x]+1,q.push(e[i].y);    }    return h[ed];}int dfs(int x,int f){    if(x==ed)return f;    int s=0,t;    for(int i=last[x];i;i=e[i].next)    {        int y=e[i].y;        if(h[y]==h[x]+1&&e[i].d&&s<f)        {            t=dfs(y,min(f-s,e[i].d));            s+=t;e[i^1].d+=t;e[i].d-=t;        }    }    if(s==0)h[x]=0;    return s;}int main(){    n=read();m=read();    for(int i=1;i<=m;i++)    {        int x=read(),y=read(),d=read(),c=read();        Ins(x,y,d,c);Ins(y,x,d,c);    }    spfa();    for(int x=1;x<=n;x++)    {        for(int i=Last[x];i;i=E[i].next)        {            int y=E[i].y;            if(f[x]+E[i].d==f[y])addedge(x,y,E[i].c);        }    }    st=1;ed=n;    int ans=0;    while(bfs())ans+=dfs(st,inf);    printf("%d",ans);}
阅读全文
1 0