携程编程大赛决赛-1004-最短路径的代价

来源:互联网 发布:软件开发毕业论文题目 编辑:程序博客网 时间:2024/05/29 06:28

这个题题意就不用说了,想了半天。

思路就是把所有的最短路径边求出来,然后再以删掉该边的花费作为代价建图,设立源点和汇点,求最大流即可。

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;const int maxn=2000;const int maxm=50000;const int inf=1<<29;struct Node{    int u;    int v;    int w;    int c;}s[maxn*maxn];struct Snode{    int u,v;}ee[maxn*maxn];int x,y,n,m,e,des,st,head[maxn],nxt[maxm],cost[maxm],pnt[maxm],dist[maxn];int we,whead[maxn],wpnt[maxm],wnxt[maxm],flow[maxm],level[maxn];int f[maxn][maxn];bool vis[maxn];queue<int> q;void AddEdge(int u,int v,int c){    pnt[e]=v;nxt[e]=head[u];cost[e]=c;head[u]=e++;    pnt[e]=u;nxt[e]=head[v];cost[e]=c;head[v]=e++;}int Spfa(int st,int des){    for(int i=0;i<=n;i++)dist[i]=inf;    dist[st]=0;    while(!q.empty())q.pop();    q.push(st);    while(!q.empty())    {int u=q.front();q.pop();vis[u]=0;for(int i=head[u];i!=-1;i=nxt[i]){    int v=pnt[i];    if(dist[v]>dist[u]+cost[i])    {dist[v]=dist[u]+cost[i];if(!vis[v]){    q.push(v);    vis[v]=1;}    }}    }    return dist[des];}void AddEdgeW(int u,int v,int f){    wpnt[we]=v;wnxt[we]=whead[u];flow[we]=f;whead[u]=we++;    wpnt[we]=u;wnxt[we]=whead[v];flow[we]=0;whead[v]=we++;}bool BFS(int st){    memset(level,0,sizeof(level));    while(!q.empty())q.pop();    q.push(st);    level[st]=1;    while(!q.empty())    {int u=q.front();q.pop();if(u==des)    return true;for(int i=whead[u];i!=-1;i=wnxt[i])    if(flow[i]&&!level[wpnt[i]])    {level[wpnt[i]]=level[u]+1;q.push(wpnt[i]);    }    }    return level[des];}int DFS(int u,int sum){    if(u==des)return sum;    for(int i=whead[u],t;i!=-1;i=wnxt[i])    {if(flow[i]&&level[wpnt[i]]==level[u]+1&&(t=DFS(wpnt[i],min(sum,flow[i])))){    flow[i]-=t;    flow[i^1]+=t;    return t;}    }    return level[u]=0;}int maxflow(){    int ans=0;    while(BFS(st))    {while(1){    int val=DFS(st,inf);    if(!val)break;    ans+=val;}    }    return ans;}int main(){    while(scanf("%d%d",&n,&m)&&(n||m))    {memset(head,-1,sizeof(head));e=we=0;scanf("%d%d",&x,&y);for(int i=0;i<m;i++){    scanf("%d%d%d%d",&s[i].u,&s[i].v,&s[i].w,&s[i].c);    AddEdge(s[i].u,s[i].v,s[i].w);}int ans=Spfa(x,y);memset(whead,-1,sizeof(whead));memset(f,0,sizeof(f));int cnt=0;for(int i=0;i<m;i++){    if(dist[s[i].u]+s[i].w==dist[s[i].v])    {if(!f[s[i].u][s[i].v]){    ee[cnt].u=s[i].u;    ee[cnt++].v=s[i].v;}f[s[i].u][s[i].v]+=s[i].c;    }    if(dist[s[i].v]+s[i].w==dist[s[i].u])    {if(!f[s[i].v][s[i].u]){    ee[cnt].u=s[i].v;    ee[cnt++].v=s[i].u;}f[s[i].v][s[i].u]+=s[i].c;    }}for(int i=0;i<cnt;i++)    AddEdgeW(ee[i].u,ee[i].v,f[ee[i].u][ee[i].v]);st=x,des=y;printf("%d\n",maxflow());    }    return 0;}


0 0
原创粉丝点击