标签:
POJ 3268 Silver Cow Party spfa。。
闲来无事水一发奶牛题睡觉好了。。马上就11好了【泪流满面
Description:n个点(1 <= n <= 1000),m条带权值(花费)有向边(1 <= m <= 1e5),给定一个目标点T,求点的价值最大值。
我们给每一个点的价值这么定义。一个点的价值 = 当前点到目标点的最小花费 + 目标点到当前点的最小花费。
Solution:
唔。。解法很simple。。对T跑spfa然后把边反转spfa。。
为什么可以这么干【唔。虽然显然。但是为了以后拿到问题分析的逻辑层次还是写一写吧。】
我们考虑每个点的价值。我们先考虑目标点到当前点的最小花费。。这个很容易求。。对T跑一次spfa。。
点的价值 = 目标点到当前点的最小花费 * 2 ?
不对。有向图。unidirectional。。
朴素的spfa寻找答案时,一条合法的边是这么定义的,u可以到达v,我们可以扩展。
我们*2得到答案的原因是u可以到达v时v不一定到达u。那我们把spfa扩展节点的条件改一下:若v可以到达u,视为u和v之间有边。
所以我们把边反转求一遍spfa。。然后找出reverse_dis[i] + dis[i]的最大值就好了。。
渣代码:
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <math.h> 6 #include <stdlib.h> 7 using namespace std; 8 const int M = 1e5 + 5; 9 const int N = 1000 + 5; 10 struct qwq{ int v, val, next; } edge[M], revedge[M]; 11 bool vis[N]; 12 int cnt = 0, revcnt = 0, n, m, T; 13 int q[N * N], head[N], revhead[N], dis[N], revdis[N]; 14 void add(int uu, int vv, int tt) 15 { 16 edge[++ cnt] = (qwq){ vv, tt, head[uu] }; head[uu] = cnt; 17 revedge[++ revcnt] = (qwq){ uu, tt, revhead[vv] }; revhead[vv] = revcnt; 18 } 19 void solve(){ 20 memset(vis, 0, sizeof(vis)); 21 memset(q, 0, sizeof(q)); 22 memset(dis, 0x3f, sizeof(dis)); 23 //back route, normal 24 vis[T] = 1; 25 int h = 0, t = 0; 26 q[++ t] = T; 27 dis[T] = 0; 28 while(h < t){ 29 int uu = q[++ h]; vis[uu] = 0; 30 for(int i = head[uu]; ~i; i = edge[i].next){ 31 int v = edge[i].v; 32 if(dis[v] > dis[uu] + edge[i].val){// 先松弛 33 dis[v] = dis[uu] + edge[i].val; 34 if(!vis[v]){ 35 vis[v] = 1; q[++ t] = v; 36 } 37 } 38 } 39 } 40 memset(vis, 0, sizeof(vis)); 41 memset(q, 0, sizeof(q)); 42 memset(revdis, 0x3f, sizeof(revdis)); 43 //go route, reverse mode QAQ 44 vis[T] = 1; 45 h = 0, t = 0; 46 q[++ t] = T; 47 revdis[T] = 0; 48 while(h < t){ 49 int uu = q[++ h]; vis[uu] = 0; 50 for(int i = revhead[uu]; ~i; i = revedge[i].next){ 51 int v = revedge[i].v; 52 if(revdis[v] > revdis[uu] + revedge[i].val){ //先松弛 QAQ 53 revdis[v] = revdis[uu] + revedge[i].val; 54 if(!vis[v]){ 55 vis[v] = 1; q[++ t] = v; 56 } 57 } 58 } 59 } 60 int mx = 0; 61 for(int i = 1; i <= n; i ++){ 62 //printf("%d %d\n", dis[i], revdis[i]); 63 if(i != T && dis[i] + revdis[i] > mx) mx = dis[i] + revdis[i]; 64 } 65 printf("%d\n", mx); 66 } 67 int main() 68 { 69 memset(head, -1, sizeof(head)); 70 memset(revhead, -1, sizeof(revhead)); 71 scanf("%d%d%d", &n, &m, &T); 72 for(int i = 1; i <= m; i ++){ 73 int uu, vv, tt; 74 scanf("%d%d%d", &uu, &vv, &tt); 75 add(uu, vv, tt); 76 } 77 solve(); 78 return 0; 79 }
POJ 3268 Silver Cow Party SPFA
标签:
原文地址:http://www.cnblogs.com/shadyqwq-juruo/p/5745257.html