题目
题解
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;
}