UVa 1599 Ideal Path

来源:互联网 发布:java分布式视频教程 编辑:程序博客网 时间:2024/04/18 10:13

题目

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