计蒜客 16959 Our Journey of Dalian Ends(最小费用最大流-mcmf)
2018-03-02 10:36
549 查看
Description
给出若干路线,问从大连到西安,途中经过上海,在保证每个城市至多经过一次的条件下的最短路径长度
Input
第一行一整数TT表示用例组数,每组用例首先输入一整数mm表示路线数量,之后mm行每行输入两个城市的名称和这两个城市之间路线的长度(m≤104)(m≤104)
Output
输出从大连到西安途经上海的最短路线长度,如果不存在合法路线则输出−1−1
Sample Input
3
2
Dalian Shanghai 3
Shanghai Xian 4
5
Dalian Shanghai 7
Shanghai Nanjing 1
Dalian Nanjing 3
Nanjing Xian 5
Shanghai Xian 8
3
Dalian Nanjing 6
Shanghai Nanjing 7
Nanjing Xian 8
Sample Output
7
12
-1
Solution
费用流,每个城市拆点限流保证至多经过一次,途径上海即从西安和大连出发有两条流量为11的流可以流到上海,故从源点向西安和大连连流量为11的边,从上海向汇点连流量为22的边(注意上海拆点后限流为22),跑一边费用流,如果最大流可以满流(即最大流为22)则说明存在合法路线,输出最小费用即可,否则无解
Code
给出若干路线,问从大连到西安,途中经过上海,在保证每个城市至多经过一次的条件下的最短路径长度
Input
第一行一整数TT表示用例组数,每组用例首先输入一整数mm表示路线数量,之后mm行每行输入两个城市的名称和这两个城市之间路线的长度(m≤104)(m≤104)
Output
输出从大连到西安途经上海的最短路线长度,如果不存在合法路线则输出−1−1
Sample Input
3
2
Dalian Shanghai 3
Shanghai Xian 4
5
Dalian Shanghai 7
Shanghai Nanjing 1
Dalian Nanjing 3
Nanjing Xian 5
Shanghai Xian 8
3
Dalian Nanjing 6
Shanghai Nanjing 7
Nanjing Xian 8
Sample Output
7
12
-1
Solution
费用流,每个城市拆点限流保证至多经过一次,途径上海即从西安和大连出发有两条流量为11的流可以流到上海,故从源点向西安和大连连流量为11的边,从上海向汇点连流量为22的边(注意上海拆点后限流为22),跑一边费用流,如果最大流可以满流(即最大流为22)则说明存在合法路线,输出最小费用即可,否则无解
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; typedef pair<int,int>P; #define maxn 20005 #define maxm 100005 #define INF 0x3f3f3f3f int head[maxn],d[maxn],s,e,no,vis[maxn],pre[maxn];//s为源点,e为汇点 struct point { int u,v,flow,next,cost; point(){}; point(int _u,int _v,int _next,int _flow,int _cost) { u=_u,v=_v,next=_next,flow=_flow,cost=_cost; } }p[maxm]; void add(int x,int y,int z,int c)//从x到y建一条容量为z,花费为c的边 { p[no]=point(x,y,head[x],z,c); head[x]=no++; p[no]=point(y,x,head[y],0,-c); head[y]=no++; } void init()//初始化 { memset(head,-1,sizeof(head)); no=0; } bool spfa() { int i,x,y; queue<int>q; memset(d,0x3f,sizeof(d)); memset(vis,false,sizeof(vis)); memset(pre,-1,sizeof(pre)); d[s]=0; vis[s]=true; q.push(s); while(!q.empty()) { x=q.front(); q.pop(); vis[x]=false; for(i=head[x];i!=-1;i=p[i].next) { if(p[i].flow&&d[y=p[i].v]>d[x]+p[i].cost) { d[y]=d[x]+p[i].cost; pre[y]=i; if(vis[y]) continue; vis[y]=true; q.push(y); } } } return d[e]!=d[e+1]; } int mcmf()//最小费用最大流 { int mincost=0,maxflow=0,minflow,i; while(spfa()) { //if(d[e]>=0)break;//可行流 minflow=INF; for(i=pre[e];i!=-1;i=pre[p[i].u]) minflow=min(minflow,p[i].flow); for(i=pre[e];i!=-1;i=pre[p[i].u]) { p[i].flow-=minflow; p[i^1].flow+=minflow; } mincost+=d[e]*minflow; maxflow+=minflow; } if(maxflow!=2)return -1; return mincost;//最小费用,最大流为maxflow } map<string,int>M; int T,n,m,E[maxn][3]; int Id(string s) { if(M.find(s)==M.end())M[s]=++n; return M[s]; } int main() { scanf("%d",&T); while(T--) { M.clear(); M["Dalian"]=1,M["Xian"]=2,M["Shanghai"]=3; n=3; scanf("%d",&m); for(int i=1;i<=m;i++) { string a,b; int d; cin>>a>>b>>d; E[i][0]=Id(a),E[i][1]=Id(b),E[i][2]=d; } init(); s=0,e=2*n+1; add(s,1,1,0),add(s,2,1,0); add(3,e,2,0); for(int i=1;i<=n;i++)add(i+n,i,i==3?2:1,0); for(int i=1;i<=m;i++) { int u=E[i][0],v=E[i][1],w=E[i][2]; add(u,v+n,1,w),add(v,u+n,1,w); } printf("%d\n",mcmf()); } }
相关文章推荐
- 计蒜客 Our Journey of Dalian Ends 拆点+最小费用最大流
- 计蒜客 Our Journey of Dalian Ends 最小费用最大流
- 计蒜客-乌鲁木齐网络赛&费用流&拆点-Our Journey of Dalian Ends
- 计蒜客 Our Journey of Dalian Ends(17新疆网赛) 费用流(思维建图)
- 计蒜客 16959 Our Journey of Dalian Ends(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-J-Our Journey of Dalian Ends
- Our Journey of Dalian Ends 乌鲁木齐网络赛 最小费用最大流
- 计蒜客:2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛:Our Journey of Dalian Ends
- Our Journey of Dalian Ends (最小费用最大流)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J.Our Journey of Dalian Ends【最小费用最大流】
- J: Our Journey of Dalian Ends
- Our Journey of Dalian Ends
- 【2017新疆网络赛】Our Journey of Dalian Ends 费用流
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J. Our Journey of Dalian Ends [网络流]
- ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends
- Our Journey of Dalian Ends【网络流】
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 [计蒜客] Our Journey of Dalian Ends
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 - J Our Journey of Dalian Ends(最小费用最大流)
- 【2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛】 J Our Journey of Dalian Ends 【拆点费用流】
- 2017 ACM 区域赛青岛站(现场赛) K Our Journey of Xian Ends