您的位置:首页 > 理论基础 > 计算机网络

计蒜客 16959 Our Journey of Dalian Ends(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J)

2017-09-20 18:03 567 查看
题目链接:Our Journey of Dalian Ends

题目大意:一张无向图,每两个城市之间有一条花费为cost的双向边,现在问能不能从西安到大连,途径香港,如果可以,输出最小花费,否则输出-1

题目思路:题目可以转化为从源点连接西安和大连,汇点上海,最大流量是否为2,是的话求最小费用最大流,把每个点都拆成两个点x⋅,x,x⋅,x之间的容量为1,费用为0(为上海的时候需要注意容量为2),双向边连接两个点x⋅−>y,y⋅−>x,这样就可以形成双向边,容量无限大,费用为两个城市之间的费用,然后冲费用流就好了

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
4000

#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MaxNode = 1e5+10;
const int MaxEdge = 1e5+10;

struct Edge{
int to,vol,cost,next;
}Edges[MaxEdge];

int Pre[MaxNode],Path[MaxNode],Dist[MaxNode],Head[MaxNode],EdgeCount;
bool vis[MaxNode];

void addedge(int u, int v, int vol, int cost){
Edges[EdgeCount].to = v;
Edges[EdgeCount].vol = vol;
Edges[EdgeCount].cost = cost;
Edges[EdgeCount].next = Head[u];
Head[u] = EdgeCount++;

Edges[EdgeCount].to = u;
Edges[EdgeCount].vol = 0;
Edges[EdgeCount].cost = -cost;
Edges[EdgeCount].next = Head[v];
Head[v] = EdgeCount++;
}

bool Spfa(int s, int t){
memset(Dist, INF, sizeof(Dist));
memset(Pre, -1, sizeof(Pre));
memset(vis, false, sizeof(vis));
Dist[s] = 0;
queue<int>Q;
Q.push(s);
vis[s] = true;
while (!Q.empty()){
int u = Q.front();
Q.pop();
vis[u] = false;
for (int e = Head[u]; e != -1; e = Edges[e].next){
int v = Edges[e].to;
if (Edges[e].vol > 0 && Dist[v] > Dist[u] + Edges[e].cost){
Dist[v] = Dist[u] + Edges[e].cost;
Pre[v] = u;
Path[v] = e;
if(!vis[v]){
vis[v] = true;
Q.push(v);
}
}
}
}
return Pre[t] != -1;
}

int MCMF(int s, int t){
int cost = 0;
int max_flow = 0;
int u, v, e;
while (Spfa(s, t)){
int f = INF;
for (u = t; u != s; u = Pre[u]){
f = min(f, Edges[Path[u]].vol);
}

for (u = t; u != s; u = Pre[u]){
e = Path[u];
Edges[e].vol -= f;
Edges[e^1].vol += f;
}
max_flow += f;
cost += f*Dist[t];
}
if(max_flow != 2) return -1;
return cost;
}

void init(){
memset(Head,-1,sizeof(Head));
EdgeCount = 0;
}

int T,m,cost[MaxNode];
map<string,int>mp;
string s1[MaxNode],s2[MaxNode];

int main(){
scanf("%d",&T);
while(T--){
init();
mp.clear();
scanf("%d",&m);
int cot = 0;
for(int i = 1;i <= m;i++){
cin>>s1[i]>>s2[i]>>cost[i];
if(mp[s1[i]] == 0){
mp[s1[i]] = ++cot;
if(s1[i] == "Shanghai") addedge(mp[s1[i]],mp[s1[i]]+m*2,2,0);
else addedge(mp[s1[i]],mp[s1[i]]+m*2,1,0);
}
if(mp[s2[i]] == 0){
mp[s2[i]] = ++cot;
if(s2[i] == "Shanghai") addedge(mp[s2[i]],mp[s2[i]]+m*2,2,0);
else addedge(mp[s2[i]],mp[s2[i]]+m*2,1,0);
}
}
for(int i = 1;i <= m;i++){
addedge(mp[s1[i]]+m*2,mp[s2[i]],INF,cost[i]);
addedge(mp[s2[i]]+m*2,mp[s1[i]],INF,cost[i]);
}
int t = 2*m+cot+1;
addedge(0,mp["Xian"],1,0);
addedge(0,mp["Dalian"],1,0);
addedge(mp["Shanghai"]+m*2,t,2,0);
printf("%d\n",MCMF(0,t));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐