poj 3268(Dijkstra+有向图的处理)

Silver Cow Party

  POJ - 3268 
题目的大意是说在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;
}


猜你喜欢

转载自blog.csdn.net/c___c18/article/details/81020848
今日推荐