最短路_POJ_3268

来源:互联网 发布:网络律师 编辑:程序博客网 时间:2024/05/01 11:17
/*最短路Dijkstra、Ford:先给距离赋值为oo,然后扫描所有边,对于起点距离不为oo更新终点距离扫描n-1遍,之后如果还能有满足更新的条件,则表明有负环Floyd:每个点间的最短距离k从1-n,k为转折点每次跟新dis[u][v] > dis[u][k] + dis[k][v]SPFA:先距离为oo,起点为0,入队列,标记在队列中,标记进入队列次数,取出点,遍历跟新,如果次数>n有环;n(1000)点,要去(x),有m(100000)条单向路,标记t(100)秒,问一个点到x,在从回来,最短的最大是多少Floyd跑一遍,选择最大就好了吧,然而无情wa了回头一想,n*n*n,2000ms也会暴掉啊,莫非暗藏玄机吗x到其他点的最短路,Dijs跑一遍就好了,问题是其他点到x点的,总不能跑n次Dijs吧据说只要把边反向一下,然后在来一遍D,那就是点到x的最短路,好有道理啊,反向之后,x出去的边就变成来的边,既可以反向进来叼叼的感觉*/#include<iostream>#include<cstdio>#include<cstring>#define Max(a,b) (a)>(b)?(a):(b)#define Min(a,b) (a)<(b)?(a):(b)#define oo 0x3f3f3f3fconst int maxn = 1010;int mp[maxn][maxn],n,m,x;int dis[maxn],dis1[maxn],vis[maxn];void Floyd(){    for(int k = 1; k <= n; k++)    {        for(int u = 1; u <= n; u++)        {            for(int v = 1; v <= n; v++)            {                if(mp[u][k] != oo && mp[k][u] != oo)                    mp[u][v] = Min(mp[u][v], mp[u][k]+mp[k][v]);            }        }    }}void Dijkstra(int s){    for(int i = 1; i <= n; i++)    {        dis[i] = mp[s][i];        vis[i] = 0;    }    vis[s] = 1;    int mi ,k;    for(int i = 0; i < n; i++)    {        mi = oo,k=s;        for(int j = 1; j <= n; j++)        {            if(!vis[j]&&mi>dis[j])            {                mi = dis[j];                k = j;            }        }        if(k == s)continue;        vis[k] = 1;        for(int j = 1; j <= n; j++)        {            if(!vis[j] &&mp[k][j]!=oo)                dis[j] = Min(dis[j], dis[k]+mp[k][j]);        }    }}int solve(){    Dijkstra(x);    memcpy(dis1,dis,sizeof(dis));    for(int i = 1; i <= n; i++)    {        for(int j = i+1; j<=n; j++)        {            mp[i][j] = mp[i][j] ^ mp[j][i];            mp[j][i] = mp[j][i] ^ mp[i][j];            mp[i][j] = mp[i][j] ^ mp[j][i];        }    }    Dijkstra(x);    int ans = dis[1]+dis1[1];    for(int i = 1; i <= n; i++)    {        ans = Max(ans, dis[i]+dis1[i]);    }    return ans;}int main(){    int u,v,val;    while(scanf("%d%d%d",&n,&m,&x)!=EOF)    {        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= n; j++)                if(i == j)                    mp[i][i] = 0;                else                    mp[i][j] = oo;        }        while(m--)        {            scanf("%d%d%d",&u,&v,&val);            if(mp[u][v]>val)                mp[u][v] = val;        }        printf("%d\n",solve());    }    return 0;}
0 0
原创粉丝点击