UVa 1599 Ideal Path

题目

UVa 1599 Ideal Path

题解

WLGQ这个题实在是恶心了一发。一开始我在担心会T,后来发现,,并不会,只是一开始写的拙劣。结构体写了又删删了又写,数组开了又删删了又开我很无奈。

主体思想,一个d[i]记录i点到n点的最短距离。先从终点BFS一遍处理出来。
从起点开始走的话,假设当前在u点,当且仅当d[u]+1=d[v]时可以走到v点。然后在这些满足条件的点里找出颜色序号最小的(我觉得刘汝佳这句话有点引入歧途的味道),其实并不用在入队的时候去找最小颜色(最小颜色下文称为col),woc我一开始还用vector排序,真是再来一个数组,D[i]表示距离起点为距离为i的点的前驱边的颜色的最小值,因为BFS肯定是一层一层搜完了的,所以处理到第i层的时候D[i]肯定已经被第i-1层的更新完了。这个时候满足d[u]+1=d[v]的节点都进队了,出队的时候我们要找最小的col,只需要比较一下v的前驱边的col和(假设v到1距离为dd)D[dd]即可,若前者大于后者就直接continue;
然后注意要加一个done数组标记节点是否被处理过。要不然好像会T?反正BFS时先搜到的一定是更优的。

代码

这题居然会有格式错误= =其实我看到Presentation error的时候一股欣喜之感,代码写的不好,很长。。。。还有maxn,maxm好像要开大一点否则RE?

#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=200000+10;
const int maxm=400000+10;
const int INF=(1<<30);
struct Edge{
    int u,v,col;
    Edge(){}
    Edge(int u,int v,int col):u(u),v(v),col(col){}
}e[maxm*2];

int read()
{
    int ret=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
    return ret;
}

int ecnt=0;
int next[maxm*2],first[maxn];
void add_edge(int u,int v,int col)
{
    next[ecnt]=first[u];first[u]=ecnt;e[ecnt++]=Edge(u,v,col);
    next[ecnt]=first[v];first[v]=ecnt;e[ecnt++]=Edge(v,u,col);
}

int n,m;
int d[maxn];
void BFS1()
{
    for(int i=1;i<=n;i++) d[i]=INF;
    queue<int>q;
    q.push(n);
    d[n]=0;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        if(u==1) break;
        for(int i=first[u];i!=-1;i=next[i])
        {
            int v=e[i].v;
            if(d[v]>d[u]+1)
            {
                d[v]=d[u]+1;
                q.push(v);
            }
        }
    }
    printf("%d\n",d[1]);
}

struct Node{
    int v,pre,precol,D;
    Node(){}
    Node(int v,int pre,int p,int D):v(v),pre(pre),precol(p),D(D){}
};

int done[maxn],pre[maxn],precol[maxn],D[maxn];
void BFS2()
{
    for(int i=1;i<=n;i++) done[i]=0,pre[i]=0,D[i]=INF,precol[i]=0;
    queue<Node>q;
    q.push(Node(1,0,0,1));
    while(!q.empty())
    {
        Node u=q.front();q.pop();
        if(done[u.v]||D[u.D]<u.precol)continue;
        done[u.v]=1;
        pre[u.v]=u.pre;
        precol[u.v]=u.precol;
        if(u.v==n) continue;
        for(int i=first[u.v];i!=-1;i=next[i])
        {
            int v=e[i].v;
            int col=e[i].col;
            if(d[v]+1==d[u.v]&&!done[v]&&col<=D[u.D+1])
            {
                q.push(Node(v,u.v,col,u.D+1));
                D[u.D+1]=min(D[u.D+1],col);
            }
        }
    }
    stack<int>st;
    for(int i=n;i!=1;i=pre[i])
        st.push(precol[i]);
    printf("%d",st.top());st.pop();
    while(!st.empty()) printf("% d",st.top()),st.pop();
    printf("\n");
}

void solve()
{
    memset(first,-1,sizeof(first));
    m=read();
    for(int i=1,u,v,col;i<=m;i++)
    {
        u=read(),v=read(),col=read();
        if(u!=v)
              add_edge(u,v,col);
    }
    BFS1();
    BFS2();
}

int main()
{
    while(scanf("%d",&n)==1) 
      solve();
    return 0;
}

你可能感兴趣的:(uva)