题目链接:。。。。。。。。。
题目大意:有一个女的要到男的家去打他的, 这男的知道了,想要了解这女的到他家断了一条路的最短时间的最坏情况。在这女的到这男的家有一条路是不通的。
思路:这条断了的路肯定是在路全通的情况下的最短中, 因为如果在这之外, 找的的路就是路全通情况下的最短路。找的了全通情况下的最短路, 依次枚举最短路中每条路断时所要走的最短路, 选取最大的值就是最后答案。
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;
}