天天看点

HDOJ 1595 find the longest of the shortest (枚举最短路+删除)

题目链接:。。。。。。。。。

题目大意:有一个女的要到男的家去打他的, 这男的知道了,想要了解这女的到他家断了一条路的最短时间的最坏情况。在这女的到这男的家有一条路是不通的。

思路:这条断了的路肯定是在路全通的情况下的最短中, 因为如果在这之外, 找的的路就是路全通情况下的最短路。找的了全通情况下的最短路, 依次枚举最短路中每条路断时所要走的最短路, 选取最大的值就是最后答案。

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;
}