WHUST 2017 Div.2 Day 15 [2017-08-06](图论八题)
来源:互联网 发布:制作相册影集软件 编辑:程序博客网 时间:2024/06/04 19:34
A - Silver Cow Party(SSSP)
POJ - 3268
题目大意
有1~N一共N个结点,每个结点都有一头奶牛,
每只奶牛都打算到结点X(1<=X<=N)来参加派对,
并且在派对结束后回到原来的结点,
每只奶牛都选择最短的路程,
一共有M条单向的路,每条路通过的时间为Ti,(单向有权)
(1 ≤ N ≤ 1000) (1 ≤ M ≤ 100,000) (1 ≤ Ti ≤ 100)
问:来回的路程最长的奶牛经过的总路程为多少?
做法
单源最短路(SSSP)问题的变种,“回家”即为从X到各点的最短路,“前往派对”即为将所有道路取反后,从X到各个点的最短路比较稀疏的图,用Dijkstra模板即可
AC-Code (C++)
Time: 47 ms Memory: 1060 kb
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<string>#include<vector>#include<functional>using namespace std;const int maxn = 1005;const int maxm = 100005;const int inf = 1000000000;int N, M, X;//结点数,道路数,原点struct Edge{int from, to, dist;Edge(int u, int v, int d) :from(u), to(v), dist(d){}};vector<Edge> edges_1;//存储正边vector<int> G_1[maxn];vector<Edge> edges_2;//存储反边vector<int> G_2[maxn];bool done[maxn];//是否已被访问int d_1[maxn];//到原点的距离int d_2[maxn];typedef pair<int, int> pii;int ans = -1;void AddEdge_1(int from, int to, int dist){edges_1.push_back(Edge(from, to, dist));int m = edges_1.size();G_1[from].push_back(m - 1);}void AddEdge_2(int from, int to, int dist){edges_2.push_back(Edge(from, to, dist));int m = edges_2.size();G_2[from].push_back(m - 1);}void dijkstra_1(void)//从原点到各点{priority_queue<pii, vector<pii>, greater<pii> >Q;for (int i = 1; i <= N; i++)d_1[i] = inf;d_1[X] = 0;memset(done, 0, sizeof(done));Q.push(pii(0, X));while (!Q.empty()){pii x = Q.top();Q.pop();int u = x.second;//u为当前结点的编号if (done[u])continue;done[u] = true;for (int i = 0; i < G_1[u].size(); i++){Edge& e = edges_1[G_1[u][i]];if (d_1[e.to]>d_1[u] + e.dist){d_1[e.to] = d_1[u] + e.dist;Q.push(pii(d_1[e.to], e.to));}}}}void dijkstra_2(void)//从各点到原点{priority_queue<pii, vector<pii>, greater<pii> >Q;for (int i = 1; i <= N; i++)d_2[i] = inf;d_2[X] = 0;memset(done, 0, sizeof(done));Q.push(pii(0, X));while (!Q.empty()){pii x = Q.top();Q.pop();int u = x.second;//u为当前结点的编号if (done[u])continue;done[u] = true;for (int i = 0; i < G_2[u].size(); i++){Edge& e = edges_2[G_2[u][i]];if (d_2[e.to]>d_2[u] + e.dist){d_2[e.to] = d_2[u] + e.dist;Q.push(pii(d_2[e.to], e.to));}}}}int main(void){scanf("%d %d %d", &N, &M, &X);for (int i = 0; i < M; i++){int a, b, c;scanf("%d %d %d", &a, &b, &c);AddEdge_1(a, b, c);AddEdge_2(b, a, c);}dijkstra_1();dijkstra_2();for (int i = 1; i <= N; i++){ans = max(ans, d_1[i] + d_2[i]);}printf("%d\n", ans);return 0;}
B - Wormholes(Bellman-Ford)
POJ - 3259
题目大意
农场主FJ有F个农场(F组数据),
一个农场有N块地(结点),编号1~N,
地与地之间有M条双向正权边,W条单向负权边(虫洞),
FJ想从农场的某点出发,经过一些结点后回到原点时,时间早于出发的时刻,
问:FJ能否在该农场实现这个愿望?
(1 ≤ N ≤ 500) (1 ≤ M ≤ 2500) (1 ≤ W ≤ 200)
做法
要使结束的时间早于开始的时间,即为图中含有负圈,即检测给定图中是否有负圈。Bellman-Ford模板题,
要注意输入正负边时的细节,以及总边数的处理,防止边数组开小了,另外注意一下重边的情况
AC-Code (C++)
Time: 125 ms Memory: 764 kb
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<string>#include<vector>#include<functional>using namespace std;const int MAXN = 505;const int MAXM = 5500;const int INF = 1000000000;int F, N, M, W;//样例数,结点数,正边数(双向),负边数(单向)int d[MAXM];//到起点距离int u[MAXM];//起点int v[MAXM];//终点int w[MAXM];//权值bool ans = false;void bellman_ford(void){for (int k = 0; k <= N - 1; k++){if (k == N - 1){ans = true;break;}bool temp = false;for (int i = 1; i <= M * 2 + W; i++){int x = u[i], y = v[i];if (d[x] < INF){int dy = d[y];d[y] = min(d[y], d[x] + w[i]);if (d[y]!=dy)temp = true;}}if (!temp)break;}return;}int main(void){scanf("%d", &F);while (F--){scanf("%d %d %d", &N, &M, &W);for (int i = 1; i <= M * 2 + W; i++){w[i] = INF;}for (int i = 1; i <= N; i++){d[i] = INF;}d[1] = 0;ans = false;for (int i = 1; i <= M; i++){int a, b, c;scanf("%d %d %d", &a, &b, &c);int j = 2 * i - 1;u[j] = a;v[j] = b;w[j] = min(w[j], c);//解决重边j++;u[j] = b;v[j] = a;w[j] = min(w[j], c);}for (int i = M * 2 + 1; i <= 2 * M + W; i++){int a, b, c;scanf("%d %d %d", &a, &b, &c);u[i] = a;v[i] = b;w[i] = min(w[i], -1*c);}bellman_ford();if (ans)printf("YES\n");elseprintf("NO\n");}return 0;}
C - Cow Contest
POJ - 3660
题目大意
有1~N一共N个结点,每个结点都有一头奶牛,
每只奶牛都打算到结点X(1<=X<=N)来参加派对,
并且在派对结束后回到原来的结点,
每只奶牛都选择最短的路程,
一共有M条单向的路,每条路通过的时间为Ti,(单向有权)
(1 ≤ N ≤ 1000) (1 ≤ M ≤ 100,000) (1 ≤ Ti ≤ 100)
问:来回的路程最长的奶牛经过的总路程为多少?
做法
单源最短路(SSSP)问题的变种,“回家”即为从X到各点的最短路,“前往派对”即为将所有道路取反后,从X到各个点的最短路比较稀疏的图,用Dijkstra模板即可
AC-Code (C++)
Time: 47 ms Memory: 1060 kb
阅读全文
0 0
- WHUST 2017 Div.2 Day 15 [2017-08-06](图论八题)
- WHUST 2017 Div.2 Day 1
- WHUST 2017 Div.2 Day 9 [2017-07-29]
- 【WHUST 2016 Individual Contest #2】解题报告
- CodeForces#207Div.2 - B. Flag Day
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) -- B. Bash's Big Day (唯一分解定理)
- Codeforces Round #332 (Div. 2)C. Day at the Beach(好题,)
- Codeforces Round #332 (Div. 2)-C Day at the Beach (排序)
- Codeforces Round #332 (Div. 2) C. Day at the Beach
- Codeforces Round #332 (Div. 2) C. Day at the Beach
- Codeforces Round #332 (Div. 2) C. Day at the Beach
- Codeforces Round #332 (Div. 2) C. Day at the Beach
- Codeforces Round #332 (Div. 2)-C. Day at the Beach
- Codeforces Round #332 (Div. 2)C. Day at the Beach
- 2017 Amsterdam CSS Day
- Day-(-2)
- 2-day(CSS)
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) B. Bash's Big Day(分拆素因子+求最多的公因子)
- pcre在mac上的安装
- android开发之PreferenceScreen使用详解
- js键盘检测
- UGUI 学习笔记 5 Raw Image
- fabirc1.0商业正式版本源码解析9——文档翻译之MSP
- WHUST 2017 Div.2 Day 15 [2017-08-06](图论八题)
- java中如何设置HTTP协议的头信息(header)
- 学习笔记之浅谈面向对象编程4(继承中的构造方法)
- 两点画线比较简单的方法
- 简单分析某个棋牌游戏的抢位置功能
- UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符
- HDU1829 A Bug's Life dfs黑白染色二分图
- QML组件之Component
- Tomcat服务器顶层结构和启动过程