1. 程式人生 > >poj 3268(Dijkstra+有向圖的處理)

poj 3268(Dijkstra+有向圖的處理)

Silver Cow Party

 題目的大意是說在2號點有一個party,所有其他點的牛都要去,同時也要回來,求在所有的牛來回的最短時間內最大值是多少。

一開始我是用了最容易想到的方法,從其他點到x點,再從x點到其他點這樣一次次的遍歷一遍,想想都成三層for迴圈了,結果肯定就是TLE》==《了,用了鄰接表,同樣TLE,沒辦法看了一下題解,原來很簡單,將圖倒過來記一次,正著記一次不就行了。

但是其中有一些要注意的地方,廢話不說,上程式碼:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<iomanip>
#include<queue>
using namespace std;
#define rep(i,a,b)   for(int i=a;i<=b;i++)
int e[1005][1005];
//int first[1010];
//int next[1010];
//int u[100005];
//int v[100005];
//int w[100005];
bool book[1005];
int disg[1005];//代表其他點去x點的最小距離
int disb[1005];//代表x點到其他點的最小距離
int MAX=0x3f3f3f3f;
int n,m,x;
int Dijkstra()
{
    memset(disb,0,sizeof(disb));
    memset(disg,0,sizeof(disg));
    rep(i,1,n)
    e[i][i]=0;
//    int k=first[star];
//    while(k!=-1)
//    {
//        dis[v[k]]=w[k];
//        k=next[k];
//    }
    rep(i,1,n)
    disg[i]=e[i][x];//這裡是從i-->x,因此下面是e[k][u]
    memset(book,0,sizeof(book));
    book[x]=1;
    rep(i,1,n)
    {
        int MIN=MAX;
        int u;
        rep(j,1,n)
        if(!book[j]&&disg[j]<MIN)
            MIN=disg[u=j];
            book[u]=1;
            rep(k,1,n)
            {
                if(e[k][u]<MAX&&!book[k])
                disg[k]=min(disg[k],disg[u]+e[k][u]);
            }
//            int k=first[u];
//            while(k!=-1)
//            {
//                dis[v[k]]=min(dis[v[k]],dis[u]+w[k]);
//                k=next[k];
//            }
//
    }
    memset(book,0,sizeof(book));//這裡一定要從新初始化
    rep(i,1,n)
    disb[i]=e[x][i];//這裡是從x-->i,因此下面是e[u][k]
    book[x]=1;
    rep(i,1,n)
    {
        int MIN=MAX;
        int u;
        rep(j,1,n)
        if(!book[j]&&disb[j]<MIN)
            MIN=disb[u=j];
            book[u]=1;
            rep(k,1,n)
            {
                if(e[u][k]<MAX&&!book[k])
                disb[k]=min(disb[k],disb[u]+e[u][k]);
            }
    }
    int ans=0;
    rep(i,1,n)
    ans=max(disb[i]+disg[i],ans);
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m>>x;
    memset(e,MAX,sizeof(e));
        rep(i,1,m)
    {
        int X,y,v;
        cin>>X>>y>>v;
        e[X][y]=v;
    }
    cout<<Dijkstra()<<endl;
    //memset(first,-1,sizeof(first));
//    rep(i,1,m)
//    {
//        cin>>u[i]>>v[i]>>w[i];
//        next[i]=first[u[i]];
//        first[u[i]]=i;
//    }

    return 0;
}