hdu-携程复赛-最短路径的代价-抠图+最小割
来源:互联网 发布:ubuntu 移除软件 编辑:程序博客网 时间:2024/06/07 16:23
被数据范围坑死了。。。
说好的m<=10000,改成了m<=11000....
把所有最短路涉及到的边抠出来。
然后建图,边的权值为边的c。
然后对图求一个最小割。
最小割割掉的所有的边即为要选调的边。
#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include<queue>using namespace std;#define INF 99999999const int maxn =1110;const int maxm =25000;const int oo = 1<<29;struct Arclist{ int cnt, head[maxn], dis[maxn]; int cur[maxn], pre[maxn], gap[maxn], aug[maxn]; struct node { int u, v, w, next; } edge[maxm]; void init(int n) { cnt = 0; std::fill_n(head, n+1, -1); } void add(int u, int v, int w) { edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt++; edge[cnt].u = v; edge[cnt].v = u; edge[cnt].w = 0; edge[cnt].next = head[v]; head[v] = cnt++; } int sap(int s, int e, int n) { int max_flow = 0, u = s; int mindis; for(int i = 0; i <= n; i++) { cur[i] = head[i]; dis[i] = 0; gap[i] = 0; } aug[s] = oo; pre[s] = -1; gap[0] = n; while(dis[s]<n) { bool flag = false; if(u==e) { max_flow += aug[e]; for(int v = pre[e]; v != -1; v = pre[v]) { int id = cur[v]; edge[id].w -= aug[e]; edge[id^1].w += aug[e]; aug[v] -= aug[e]; if(edge[id].w==0) u = v; } } for(int id = cur[u]; id != -1; id = edge[id].next) { int v = edge[id].v; if(edge[id].w>0 && dis[u]==dis[v]+1) { flag = true; pre[v] = u; cur[u] = id; aug[v] = std::min(aug[u], edge[id].w); u = v; break; } } if(flag==false) { if(--gap[dis[u]]==0) break; mindis = n; cur[u] = head[u]; for(int id = head[u]; id != -1; id = edge[id].next) { int v = edge[id].v; if(edge[id].w>0 && dis[v]<mindis) { mindis = dis[v]; cur[u] = id; } } dis[u] = mindis+1; ++gap[dis[u]]; if(u!=s) u = pre[u]; } } return max_flow; }} G;struct gra{ struct list { int u,v,w,c,next; } edge[maxm]; int head[maxn]; int nums; void init() { nums=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w,int c) { edge[nums].u=u;edge[nums].v=v; edge[nums].c=c;edge[nums].w=w; edge[nums].next=head[u];head[u]=nums++; }}gs;int dij(int st,int ed,int n){ int i; int dis[maxn]; int vis[maxn]; for(i=1;i<=n;i++) { dis[i]=INF; vis[i]=0; } dis[st]=0; while(1) { int minn=INF; int x; for(i=1;i<=n;i++) { if(vis[i])continue; if(minn>dis[i]) { minn=dis[i]; x=i; } } if(minn==INF)break; vis[x]=1; for(i=gs.head[x];i!=-1;i=gs.edge[i].next) { int v=gs.edge[i].v; int w=gs.edge[i].w; if(vis[v])continue; if(dis[v]>dis[x]+w)dis[v]=dis[x]+w; } } //for(i=1;i<=n;i++)cout<<dis[i]<<" "; // cout<<endl; queue<int>que; while(!que.empty())que.pop(); que.push(ed); memset(vis,0,sizeof(vis)); vis[ed]=1; while(!que.empty()) { int x=que.front(); que.pop(); if(x==st)continue; for(i=gs.head[x];i!=-1;i=gs.edge[i].next) { int u=gs.edge[i].v; int w=gs.edge[i].w; int c=gs.edge[i].c; if(dis[u]+w==dis[x]) { // cout<<u<<"-"<<x<<":"<<c<<endl; G.add(u,x,c); if(!vis[u])que.push(u); vis[u]=1; } } } return G.sap(st,ed,n);}int main(){ int n,m,st,ed,a,b,w,c; while(~scanf("%d%d",&n,&m)&&(n||m)) { gs.init(); scanf("%d%d",&st,&ed); for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&a,&b,&w,&c); gs.add(a,b,w,c); gs.add(b,a,w,c); } G.init(maxn-1); cout<<dij(st,ed,n)<<endl; } return 0;}
0 0
- hdu-携程复赛-最短路径的代价-抠图+最小割
- HDU携程决赛最短路径的代价/USTC 1280 Finding Shortest Path 求最短路边+最小割
- 携程编程决赛-最短路径的代价
- hdu 5294 Tricks Device (最小割+最短路径+Dinic模板)
- 携程编程大赛决赛-1004-最短路径的代价
- USTC 1280 / 携程决赛1004 最短路径的代价
- USTC 1280 / 携程决赛1004 最短路径的代价
- 【最短路+最小费用】hdu 3790 最短路径问题
- hdu 3790 最短路径问题(最短路径+最小费用)
- hdu 最短路径
- hdu 最短路径
- hdu 1358 floyd+输出字典需最小最短路径
- hdu 1385 spfa和floyd,dijkstra记录最短最小字典序的路径
- hdu 1385 Minimum Transport Cost(floyd打印最小字典序的最短路径)
- 一个人的旅行 HDU 最短路径
- HDU 1142 最短路径的数量
- hdu 4738 Caocao's Bridges 【求最小代价的割边(桥)】
- hdu 5889 Barricade (最短路的最小割)
- dede:list 判断“头条”、“推荐”从而添加对应的小图标
- oracle 压缩索引
- 协议分析之滑动窗口机制
- android学习-1-图片轮显及异步加载缓存
- EditText中输入密码可见的简单实现
- hdu-携程复赛-最短路径的代价-抠图+最小割
- 接口和抽象类有什么区别
- Guide Window
- 反射与正则
- android的service本地服务的理解
- C#开发——winform中将Excel数据导入DataGridView
- java 分页技术
- HTML笔记——HTML CSS样式简介
- 火狐和谷歌浏览器屏蔽键盘按键Backspace回退网页