携程编程大赛决赛-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
- 携程编程大赛决赛-1004-最短路径的代价
- 携程编程决赛-最短路径的代价
- USTC 1280 / 携程决赛1004 最短路径的代价
- USTC 1280 / 携程决赛1004 最短路径的代价
- HDU携程决赛最短路径的代价/USTC 1280 Finding Shortest Path 求最短路边+最小割
- hdu-携程复赛-最短路径的代价-抠图+最小割
- CodingTrip - 携程编程大赛 (决赛)1004 最短路最小割
- Opnet 一个简单的网络实现Dijkstra最短路径算法,路径代价为跳数加排队延时
- Windows Shell编程-第六章.快捷方式的最短路径
- 编程算法 - 迷宫的最短路径 代码(C++)
- 华为编程大赛决赛题
- 最短路径的实现
- 迷宫的最短路径
- 最短路径的实现
- 迷宫的最短路径
- 图的最短路径
- 再谈图的最短路径
- 迷宫的最短路径
- 全角半角转换工具类
- 法国大使认同中国是一只醒狮 中法加强反恐合作
- database psu 11.2.0.3.0 到11.2.0.3.9
- 病毒—Win32/Gamarue
- -------------------Android代码优化——使用Android lint工具
- 携程编程大赛决赛-1004-最短路径的代价
- ant 打包android应用
- Linker Use static Libraries
- ProxyFactory的xml配置方式
- C语言里面的栈和堆
- Makefile文件变量的定义规则
- Python __new__与__init__说明
- struct 字节对齐详解
- android开发笔记之一些有用资料的汇总