【题目】
Bender所在的区域,可以看作一个n个点(街角),m条边(街)的无向图,每条边有一个运动难度,通过这条边所消耗的时间等于其运动难度除以Bender的行动能力。而每到一个新的街角,由于示威者们都拿着区域性酒精转转化器,Bender的酒精含量会降低,造成Bender的行动能力都会变成原来的十分之一。
Bender终于回到了基地,他将经历告诉了Fry。Fry问他怎样选择的道路。Bender当然是选择时间最少的,而且使自己尽量清醒的。
【题解】可以将经过的每条边的时间看作总时间上的一位数。最少时间必定是最少位数上的最小数。从终点可能能够连边到其他点,代价为零,将这些点也记为终点,记录他们到终点的层数。从起点开始枚最小层数,从这一层一层层推回去,每次都取最小的边权,并将满足的点入列。
【代码】
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=100005;
struct data{
int v,nxt,w;
}e[maxn<<1];
int n,m,fst[maxn],ans[maxn],tot=0;
int pas[maxn],cen[maxn],d[maxn],cnt=0;
bool vst[maxn],inz[maxn],inq[maxn];
inline int get(){
char c;while(!isdigit(c=getchar()));
int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
return v;
}
inline void add(int x,int y,int z){
e[++cnt].v=y;e[cnt].w=z;e[cnt].nxt=fst[x];fst[x]=cnt;
}
inline void bfs_find_w_zero(){
queue<int>q;
memset(inz,0,sizeof(inz));
inz[n]=1;pas[n]=0;q.push(n);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=fst[x];i;i=e[i].nxt){
int y=e[i].v;
if(!inz[y] && !e[i].w)inz[y]=1,pas[y]=pas[x]+1,q.push(y);
}
}
//for(int i=1;i<=n;++i)if(inz[i])printf("%d \n",i);
}
inline void bfs_get_cen(){
queue<int>q;
memset(vst,0,sizeof(vst));
memset(cen,0x3f,sizeof(cen));
q.push(1);vst[1]=1;cen[1]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=fst[x];i;i=e[i].nxt){
int y=e[i].v;
if(cen[y]>cen[x]+1){
cen[y]=cen[x]+1;
if(!vst[y])vst[y]=1,q.push(y);
}
}
}
//- for(int i=1;i<=n;++i)printf("%d %d\n",i,cen[i]);
}
inline void bfs_get_ans(){
int t=maxn;int l=1,r=0,p[maxn];
memset(inq,0,sizeof(inq));
memset(d,0,sizeof(d));
for(int i=1;i<=n;++i)if(inz[i])t=min(t,cen[i]);
for(int i=1;i<=n;++i)if(cen[i]==t && inz[i])p[++r]=i,inq[i]=1,d[i]=pas[i];
if(inq[1]){
printf("0\n%d\n",d[1]+1);
return;
}
while(l<=r){
int rr=r;t=maxn;
for(int i=l;i<=rr;++i){
int x=p[i];
// printf(" %d\n",x);
for(int j=fst[x];j;j=e[j].nxt){
int y=e[j].v;
if(cen[y]+1==cen[x] && !inz[y])t=min(t,e[j].w);
}
}
if(t==maxn)break;
ans[++tot]=t;
for(int i=l;i<=rr;++i){
int x=p[i];
for(int j=fst[x];j;j=e[j].nxt){
int y=e[j].v;
if(cen[y]+1==cen[x] && e[j].w==t){
if(!inq[y])d[y]=d[x],p[++r]=y,inq[y]=1;
else if(d[y]>d[x])d[y]=d[x];
}
}
}
l=rr+1;
}
for(int i=1;i<=tot;++i)printf("%d",ans[i]);
printf("\n%d\n",tot+d[1]+1);
}
int main(){
n=get();m=get();
for(int i=1;i<=m;++i){
int x=get()+1,y=get()+1,z=get();
add(x,y,z);add(y,x,z);
}
bfs_find_w_zero();
bfs_get_cen();
bfs_get_ans();
return 0;
}