发一下牢骚和主题无关:
标题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=115
标题析分:这肯定是一条求最短路的题,最开始的设法是用floyd算法来做,结果喜剧的TLE。
int Map[1001][1001]; int dp[1001][1001]; int a[100]; int main() { int t,i,j,k; int n,m,p,q; int s, e, w; scanf("%d", &t); while(t--) { scanf("%d %d %d %d", &n, &m, &p, &q); for(i = 0; i < n; ++i) scanf("%d", &a[i]); for(i = 1; i <= m; ++i) for(j = 1; j <= m; ++j) Map[i][j] = 1e7; for(i = 0; i < p; ++i) { scanf("%d %d %d", &s, &e, &w); Map[s][e] = w; Map[e][s] = w; } memcpy(dp, Map, sizeof(Map)); for(k = 1; k <= m; ++k) for(i = 1; i <= m; ++i) for(j = 1; j <= m; ++j) dp[i][j] = dp[i][j] < dp[i][k] + dp[k][j] ? dp[i][j] : dp[i][k] + dp[k][j]; s = 1e7; for(i = 0; i < n; ++i) s = s < dp[a[i]][q] ? s : dp[a[i]][q]; printf("%d\n", s); } return 0; }
没办法然后想着用广搜来做,居然过了,哎呀,心伤得很啊~
#include<stdio.h> #include<string.h> struct EDGE { int to; int w; }; EDGE edge[1001][1001];//edge[i][0].to寄存的是节点i可达的节点数 int dp[1001]; int a[100]; int Queue[2001]; bool used[1001]; int BFS(int n, int q) { int head, tail,i; int temp,j; int ans = 1e7; for(i = 0; i < n; ++i)//对队军在所的每个市城行进广搜 { memset(used, 0, sizeof(used)); Queue[0] = a[i]; used[a[i]] = true; dp[a[i]] = 0; head = 0; tail = 0; while(head <= tail) { temp = Queue[head]; if(temp == q)//历遍到终点,跳出循环 { ans = ans < dp[temp] ? ans : dp[temp]; break; } for(j = 1; j <= edge[temp][0].to; ++j) { //该节点没有用过,或者用过,但有更优的路径 if(!used[edge[temp][j].to] || dp[edge[temp][j].to] > dp[temp] + edge[temp][j].w) { used[edge[temp][j].to] = true; Queue[++tail] = edge[temp][j].to; dp[edge[temp][j].to] = dp[temp] + edge[temp][j].w; } }//end for j ++head; }//end for while }//end for i return ans; } int main() { int t,i; int n,m,p,q; int s, e, w; scanf("%d", &t); while(t--) { scanf("%d %d %d %d", &n, &m, &p, &q); for(i = 0; i < n; ++i) scanf("%d", &a[i]); for(i = 1; i <= m; ++i) edge[i][0].to = 0; for(i = 0; i < p; ++i) { scanf("%d %d %d", &s, &e, &w); ++edge[s][0].to; edge[s][edge[s][0].to].to = e; edge[s][edge[s][0].to].w = w; ++edge[e][0].to; edge[e][edge[e][0].to].to = s; edge[e][edge[e][0].to].w = w; } s = BFS(n, q); printf("%d\n", s); } return 0; }
反向广搜为什么就不对了呢?
#include<stdio.h> #include<string.h> struct EDGE { int to; int w; }; EDGE edge[1001][1001]; int dp[1001]; int a[100]; int Queue[2001]; //终点标记为-1,其余点未拜访标记为0,拜访过标记为1; int used[1001]; int BFS(int n, int q) { int head, tail; int temp,j; int ans = 1e7; int count = 0; Queue[0] = q; used[q] = 1; dp[q] = 0; head = 0; tail = 0; while(head <= tail) { temp = Queue[head]; if(used[temp] == -1)//历遍到终点,跳出循环 { ans = ans < dp[temp] ? ans : dp[temp]; ++count; if(count == n) break; } for(j = 1; j <= edge[temp][0].to; ++j) { //该节点没有用过,或者用过,但有更优的路径 if(used[edge[temp][j].to] <= 0 || dp[edge[temp][j].to] > dp[temp] + edge[temp][j].w) { used[edge[temp][j].to] = !used[edge[temp][j].to] ? 1 : used[edge[temp][j].to]; Queue[++tail] = edge[temp][j].to; dp[edge[temp][j].to] = dp[temp] + edge[temp][j].w; } }//end for j ++head; }//end for while return ans; } int main() { int t,i; int n,m,p,q; int s, e, w; scanf("%d", &t); while(t--) { memset(used, 0, sizeof(used)); scanf("%d %d %d %d", &n, &m, &p, &q); for(i = 0; i < n; ++i) { scanf("%d", &a[i]); used[a[i]] = -1; } for(i = 1; i <= m; ++i) edge[i][0].to = 0; for(i = 0; i < p; ++i) { scanf("%d %d %d", &s, &e, &w); ++edge[s][0].to; edge[s][edge[s][0].to].to = e; edge[s][edge[s][0].to].w = w; ++edge[e][0].to; edge[e][edge[e][0].to].to = s; edge[e][edge[e][0].to].w = w; } s = BFS(n, q); printf("%d\n", s); } return 0; }
文章结束给大家分享下程序员的一些笑话语录: 这个世界上只有10种人:懂得二进制的和不懂得二进制的。