题目连接 : https://nanti.jisuanke.com/t/A1256

Life is a journey, and the road we travel has twists and turns, which sometimes lead us to unexpected places and unexpected people.

Now our journey of Dalian ends. To be carefully considered are the following questions.

Next month in Xian, an essential lesson which we must be present had been scheduled.

But before the lesson, we need to attend a wedding in Shanghai.

We are not willing to pass through a city twice.

All available expressways between cities are known.

What we require is the shortest path, from Dalian to Xian, passing through Shanghai.

Here we go.

Input Format

There are several test cases.

The first line of input contains an integer tt which is the total number of test cases.

For each test case, the first line contains an integer m~(m\le 10000)m (m≤10000) which is the number of known expressways.

Each of the following mm lines describes an expressway which contains two string indicating the names of two cities and an integer indicating the length of the expressway.

The expressway connects two given cities and it is bidirectional.

Output Format

For eact test case, output the shortest path from Dalian to Xian, passing through Shanghai, or output -1−1 if it does not exist.

样例输入复制

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

样例输出复制

7
12
-1 题目大意是 ,给你两个地方中间的距离,让你从求西安到大连的最短路径,要求中途必须经过上海,而且每个点只能走一次。 啦啦啦 : 刚刚和队友补题补到这里了,算是重现了一遍网络赛吧,刚刚学了网络流没几天这题就被我发现了,之前做过一道从1到N,再从N回到1,每个边只能走一次这个题,
莫名感觉有点像,直接开的网络流,我屁颠屁颠的跑去建图了,最后还是没出来,哎,我还是继续加油刷题吧。。。 题解 : 这道题确实是个网络流的题目,而且是个费用流,首先我们很容易想到,每个点只能走一次,拆点是必须的,拆成两个点,连一条线,流量为1 ,一个只能进,另一个只能出,
然后如何确定这个一定经过上海呢,先从西安跑到上海,在从上海跑到大连,如果真的想了就发现这个不对劲,首先网络流模型,反向边是个精髓,它可以反悔,然后你可能会把之前要走
的边反悔掉,第二次网络流导致从西安到上海走不了了,如果直接两边迪杰斯特拉的话,两个最短路加拆边很明显不一定是最小那样也错了,那么就要想别滴办法了,首先这题的图是无向的
那么我们先建立一个双向边之后,把上海作为起点,大连和西安连在新建里的汇点上,然后图就完事了。 AC代码:
#include<bits/stdc++.h>
using namespace std;
map<string,int> mp;
#define INFINITE 1 << 26
#define MAX_NODE 80005
#define MAX_EDGE_NUM 80005
typedef long long ll;
struct Edge{
int to;
int vol;
int cost;
int next;
};
Edge gEdges[MAX_EDGE_NUM]; int gHead[MAX_NODE];
int gPre[MAX_NODE];
int gPath[MAX_NODE];
int gDist[MAX_NODE]; int gEdgeCount;
void InsertEdge(int u, int v, int vol, int cost){
gEdges[gEdgeCount].to = v;
gEdges[gEdgeCount].vol = vol;
gEdges[gEdgeCount].cost = cost;
gEdges[gEdgeCount].next = gHead[u];
gHead[u] = gEdgeCount++; gEdges[gEdgeCount].to = u;
gEdges[gEdgeCount].vol = ; //vol为0,表示开始时候,该边的反向不通
gEdges[gEdgeCount].cost = -cost; //cost 为正向边的cost相反数,这是为了
gEdges[gEdgeCount].next = gHead[v];
gHead[v] = gEdgeCount++;
} //假设图中不存在负权和环,SPFA算法找到最短路径/从源点s到终点t所经过边的cost之和最小的路径
bool Spfa(int s, int t){
memset(gPre, -, sizeof(gPre));
memset(gDist, 0x7F, sizeof(gDist));
gDist[s] = ;
queue<int> Q;
Q.push(s);
while (!Q.empty()){//由于不存在负权和环,因此一定会结束
int u = Q.front();
Q.pop(); for (int e = gHead[u]; e != -; e = gEdges[e].next){
int v = gEdges[e].to;
if (gEdges[e].vol > && gDist[u] + gEdges[e].cost < gDist[v]){
gDist[v] = gDist[u] + gEdges[e].cost;
gPre[v] = u; //前一个点
gPath[v] = e;//该点连接的前一个边
Q.push(v);
}
}
} if (gPre[t] == -) //若终点t没有设置pre,说明不存在到达终点t的路径
return false;
return true;
} int MinCostFlow(int s, int t){
int cost = ;
int flow = ;
while (Spfa(s, t)){
int f = INFINITE;
for (int u = t; u != s; u = gPre[u]){
if (gEdges[gPath[u]].vol < f)
f = gEdges[gPath[u]].vol;
}
flow += f;
cost += gDist[t] * f;
for (int u = t; u != s; u = gPre[u]){
gEdges[gPath[u]].vol -= f; //正向边容量减少
gEdges[gPath[u]^].vol += f; //反向边容量增加
}
}
if(flow==) return cost;
else return -;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
memset(gHead,-,sizeof(gHead));
gEdgeCount=;
mp.clear();
mp["Dalian"]=;
mp["Shanghai"]=;
mp["Xian"]=;
int ge=;
int n;
scanf("%d",&n);
int nn=n*;
for(int i=;i<n;i++){
string a,b;
int c;
cin>>a;
cin>>b;
cin>>c;
if(!mp[a]) mp[a]=ge++;
if(!mp[b]) mp[b]=ge++;
if(mp[a]!=&&mp[b]!=){
InsertEdge(mp[a]+nn,mp[b],,c);
InsertEdge(mp[b]+nn,mp[a],,c);
}
else if(mp[a]==){
InsertEdge(mp[a],mp[b],,c);
}
else{
InsertEdge(mp[b],mp[a],,c);
}
}
for(int i=;i<ge;i++){
if(i!=){
InsertEdge(i,i+nn,,);
}
}
int e=*n;
InsertEdge(,e,,);
InsertEdge(,e,,);
int dd=MinCostFlow(,e);
printf("%d\n",dd);
}
return ;
}

2017乌鲁木齐网络赛 j 题的更多相关文章

  1. 2017乌鲁木齐网络赛 J题 Our Journey of Dalian Ends ( 最小费用最大流 )

    题目链接 题意 : 给出一副图,大连是起点,终点是西安,要求你求出从起点到终点且经过中转点上海的最小花费是多少? 分析 : 最短路是最小费用最大流的一个特例,所以有些包含中转限制或者经过点次数有限制的 ...

  2. luogu 1327 数列排序 & 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 J题 循环节

    luogu 1327 数列排序 题意 给定一个数列\(\{an\}\),这个数列满足\(ai≠aj(i≠j)\),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? ...

  3. 2013 长沙网络赛J题

    思路:这题对于其他能退出所有值的情况比较好像,唯一不能确定的是XXOXXOXXOXX这个形式的序列,其中XX表示未知,O表示已知. 我们令num[1]=0,那么num[4]=sum[3]-sum[2] ...

  4. 2013 ACM/ICPC 长沙网络赛J题

    题意:一个数列,给出这个数列中的某些位置的数,给出所有相邻的三个数字的和,数列头和尾处给出相邻两个数字的和.有若干次询问,每次问某一位置的数字的最大值. 分析:设数列为a1-an.首先通过相邻三个数字 ...

  5. hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

    题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...

  6. 2017乌鲁木齐区域赛D题Fence Building-平面图的欧拉公式

    这个题B站上面有这题很完整的分析和证明,你实在不懂,可以看看这个视频  https://www.bilibili.com/video/av19849697?share_medium=android&a ...

  7. Sum 南京网络赛J题

    题意: 统计每个数的因子的对数,如果因子能被某个平方数整除,则不统计在内,每对因子有序 解析: 我们对某个数n进行质因子分解,如果某个质因子的指数大于2则 f(n) = 0, 例 N = X3 * M ...

  8. 2017北大校赛 J题 pairs

    题目链接 http://poj.openjudge.cn/practice/C17J/ orz 原来是一道无脑枚举题目 只是很卡常数而已 复杂度算错也是很醉orz 当时怎么没想着优化常数呢 题解:枚举 ...

  9. [2019上海网络赛J题]Stone game

    题目链接 CSLnb! 题意是求出给定集合中有多少个合法子集,合法子集的定义为,子集和>=总和-子集和$\& \&$子集和-(子集的子集和)<=总和-子集和. 其实就是很简 ...

随机推荐

  1. JAVA企业级开发-jdbc入门(09)

    一. jdbc介绍 JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JD ...

  2. abap table control里面各种属性和事件的写法

    SAP中,Table Control是在Screen中用的最广泛的控件之一了,可以实现对多行数据的编辑. 简单来说,Table Control是一组屏幕元素在Screen上的重复出现,这就是它与普通屏 ...

  3. Javascript 给table动态增、删除行

    操作 HTML DOM Table 对象 即可 http://www.runoob.com/jsref/dom-obj-table.html 动态给一个元素焦点,用focus()方法

  4. JMeter(5) JMeter之BeanShell使用

    BeanShell介绍 BeanShell是用Java写成的,一个小型的.免费的.可以下载的.嵌入式的Java源代码解释器,具有对象脚本语言特性.本篇只记录一下基本的使用.有以下五个组件: Beans ...

  5. java--时间日期用法

    转载大神 https://www.cnblogs.com/Mr-Lyu/p/5736152.html https://blog.csdn.net/yf198708/article/details/51 ...

  6. Jmeter4.0----录制脚本(4)

    1.前言 Jmeter录制脚本有两种方式.1.通过第三方工具录制比如:Badboy,然后转化为jmeter可用的脚本:2.使用jmeter本身自带的录制脚本功能. 对于测试小白来说可用先使用jmete ...

  7. AWR实战分析之----direct path read temp

    http://blog.sina.com.cn/s/blog_61cd89f60102eej1.html 1.direct path read temp select TOTAL_BLOCKS,USE ...

  8. 学习 primer 第8章 IO库 小结

    iostream处理控制台IO fstream处理命名文件IO stringstream完成内存string的IO 非常重要!!!!!!!!!!  ========================== ...

  9. docker jetty启动时报错 failed setting default capabilities.

    docker 容器中jetty启动fail ,查看/var/log/jetty中的日志发现具体错误信息如下: failed setting default capabilities.set_caps( ...

  10. jsp-简单的猜数小游戏

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...