计蒜客-乌鲁木齐网络赛&费用流&拆点-Our Journey of Dalian Ends
2017-09-13 15:30
429 查看
https://nanti.jisuanke.com/t/16959
给定一个图,问你从 西安出发,经过上海,到达大连,最小的花费是多少。要求每一个城市只能经过一次。。
一直在想能不能改dij。。。
正确思路:建立一个网络流&拆点。s连接 西安和大连的入点,上海的拆点连接 上海。跑一遍费用流。
注意 每个边都是可以过好多次的,所以边的权为inf。。
但是每个点只能跑一次,所以点的是1.
给定一个图,问你从 西安出发,经过上海,到达大连,最小的花费是多少。要求每一个城市只能经过一次。。
一直在想能不能改dij。。。
正确思路:建立一个网络流&拆点。s连接 西安和大连的入点,上海的拆点连接 上海。跑一遍费用流。
注意 每个边都是可以过好多次的,所以边的权为inf。。
但是每个点只能跑一次,所以点的是1.
#include <iostream> #include<queue> #include<cstring> #include <cstdio> #include <map> using namespace std; typedef long long ll; typedef int Type; const int N=12000*4; const Type inf=0x3f3f3f3f; struct edge{ int u,v; Type cap, flow, cost; edge() {} edge(int from,int to,int c,int f,int co):u(from),v(to),cap(c),flow(f),cost(co){} }; map<string,int>mp; struct MCMF{ int n,m; vector<edge>es; vector<int>G ; int inq ;//是否在队列中 Type d ;//SPFA时总费用 int p ;//上一条弧 Type a ;//可改进量 void init(int n){ this->n=n; for(int i=0; i<n; i++)G[i].clear(); es.clear(); } void add_edge(int u,int v,Type cap,Type cost){ es.push_back(edge(u, v, cap, 0, cost)); es.push_back(edge(v, u, 0, 0, -cost)); m=es.size(); G[u].push_back(m-2); G[v].push_back(m-1); } bool spfa(int s,int t,Type& flow,Type& cost){ memset(inq, 0, sizeof(inq)); for(int i=0; i<n; i++)d[i]=inf; d[s]=0;inq[s]=1;p[s]=0;a[s]=inf; queue<int>q; q.push(s); while(!q.empty()){ int u=q.front();q.pop();inq[u]=0; for(int i=0; i<G[u].size(); i++){ edge& e=es[G[u][i]]; int v=e.v; if(e.cap>e.flow && d[v]>d[u]+e.cost){ //在新流下考虑最小费用 d[v]=d[u]+e.cost; a[v]=min(a[u], e.cap-e.flow); p[v]=G[u][i]; if(!inq[v]){ inq[v]=1; q.push(v);} } } } if(d[t]==inf)return false; flow+=a[t],cost+=a[t]*d[t]; int u=t; while(u!=s){ es[p[u]].flow+=a[t]; es[p[u]^1].flow-=a[t]; u=es[p[u]].u; } return true; } Type Mincost(int s,int t){ Type flow=0, cost=0; while(spfa(s,t,flow,cost)); // cout<<flow<<endl; if(flow!=2) return -1; return cost; } }x; int n,m; int main() { int c,t,num; string a,b; scanf("%d",&t); while(t--){ scanf("%d",&m); num=1; int kk=m*2; x.init(m*5); mp.clear(); for(int i=0;i<m;i++){ cin>>a>>b>>c; if(!mp[a]){ mp[a]=num++; if(a=="Shanghai") x.add_edge(mp[a],mp[a]+kk,2,0); else x.add_edge(mp[a],mp[a]+kk,1,0); } if(!mp[b]){ if(b=="Shanghai") x.add_edge(mp[b],mp[b]+kk,2,0); else x.add_edge(mp[b],mp[b]+kk,1,0); } x.add_edge(mp[a]+kk,mp[b],inf,c); x.add_edge(mp[b]+kk,mp[a],inf,c); //cout<<mp[a]<<"bq"<<mp[b]<<c<<endl; } x.add_edge(0,mp["Dalian"],1,0); x.add_edge(0,mp["Xian"],1,0); x.add_edge(mp["Shanghai"]+kk,kk*2+1,2,0); //cout<<"!!!"<<num<<endl; printf("%d\n",x.Mincost(0,kk*2+1)); } return 0; }
相关文章推荐
- 计蒜客: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-ICPC 亚洲区(乌鲁木齐赛区)网络赛 - J Our Journey of Dalian Ends(最小费用最大流)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J. Our Journey of Dalian Ends [网络流]
- Our Journey of Dalian Ends 乌鲁木齐网络赛 最小费用最大流
- 计蒜客 Our Journey of Dalian Ends(17新疆网赛) 费用流(思维建图)
- 【2017新疆网络赛】Our Journey of Dalian Ends 费用流
- ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J.Our Journey of Dalian Ends【最小费用最大流】
- 计蒜客 16959 Our Journey of Dalian Ends(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 [计蒜客] Our Journey of Dalian Ends
- 计蒜客 Our Journey of Dalian Ends 最小费用最大流
- 计蒜客 16959 Our Journey of Dalian Ends(最小费用最大流-mcmf)
- 计蒜客 Our Journey of Dalian Ends 拆点+最小费用最大流
- Our Journey of Dalian Ends (最小费用最大流)
- Our Journey of Dalian Ends【网络流】
- Our Journey of Dalian Ends
- J: Our Journey of Dalian Ends
- 2017ACM-ICPC 青岛 K.Our Journey of Xian Ends