题目链接:。。。。。。。。。
题目大意:有一个女的要到男的家去打他的, 这男的知道了,想要了解这女的到他家断了一条路的最短时间的最坏情况。在这女的到这男的家有一条路是不通的。
思路:这条断了的路肯定是在路全通的情况下的最短中, 因为如果在这之外, 找的的路就是路全通情况下的最短路。找的了全通情况下的最短路, 依次枚举最短路中每条路断时所要走的最短路, 选取最大的值就是最后答案。
code:
#include <stdio.h> #include <string.h> #define inf 0x7fffffff struct { int v, time, next; }edge[2000002]; int m = 0, n = 0, que[10002], head[1002], dist[1002], visit[1002], used[1002], pre[1002]; void spfa(int u, int v, int c)//u, v表示要删除的边 { int i = 0, j = 0, cur = 0, item = 0, front = 0, rear = 0; for(i = 0; i<=n; i++) { used[i] = visit[i] = 0; dist[i] = inf; if(c == 0) pre[i] = -1; } dist[n] = 0; que[rear] = n; rear = (rear+1)%10000; visit[n] = used[n] = 1; while(front != rear) { cur = que[front]; front = (front+1)%10000; item = head[cur]; used[cur] = 0; while(item != -1) { if(((cur != u || edge[item].v != v) && (cur != v || edge[item].v != u)) && dist[edge[item].v]>dist[cur]+edge[item].time) { dist[edge[item].v]=dist[cur]+edge[item].time; if(c == 0) pre[edge[item].v] = cur; if( visit[edge[item].v]>n) { return; } if(used[edge[item].v] == 0) { used[edge[item].v] = 1; visit[edge[item].v]++; que[rear] = edge[item].v; rear = (rear+1)%10000; } } item = edge[item].next; } } } void solve() { int i = 0, j = 0, cur = 0, item = 0, time = 0; cur = 1, item = pre[cur]; while(item != -1) { spfa(cur, item, 1);//cur, item 表示最短路中的一条边 cur = item; item = pre[cur]; if(time<dist[1]) time = dist[1]; } printf("%d\n",time); } int main() { int i = 0, j = 0, u = 0, v = 0, time = 0, count = 0; while(scanf("%d %d",&n, &m) != EOF) { memset(head, -1, sizeof(head)); count = 0; for(i = 0; i<m; i++) { scanf("%d %d %d",&u, &v, &time); edge[count].v = v; edge[count].time = time; edge[count].next = head[u]; head[u] = count++; edge[count].v = u; edge[count].time = time; edge[count].next = head[v]; head[v] = count++; } spfa(-1, -1, 0);//用0表示需要记录下这条最短路, 1表示不需要 solve(); } return 0; }