传送门
本题让给出一个状态分配方案使得从
1
1
1到
n
n
n的最短路最大。
考虑设 d i s [ i ] [ j ] dis[i][j] dis[i][j]为从第 i i i个城市处于状态 j j j( j = 0 , 1 j=0,1 j=0,1)出发到达 n n n城市的最短路的最大值,那么有方程 d i s [ i ] [ j ] = m i n w [ i ] [ k ] = j { m a x { d i s [ k ] [ 0 ] , d i s [ k ] [ 1 ] } + 1 } dis[i][j]=min_{w[i][k]=j}\{max\{dis[k][0],dis[k][1]\}+1\} dis[i][j]=minw[i][k]=j{max{dis[k][0],dis[k][1]}+1}成立,于是倒着 b f s bfs bfs来更新 d i s dis dis即可,然后用数组记录最优转移,最后能够求出所有的 d i s [ i ] [ 0 ] , d i s [ i ] [ 1 ] dis[i][0],dis[i][1] dis[i][0],dis[i][1],若 d i s [ i ] [ 0 ] > d i s [ i ] [ 1 ] dis[i][0]>dis[i][1] dis[i][0]>dis[i][1]我们让 i i i的点权为 0 0 0,否则为 1 1 1,输出即可。
int h[maxn],ee=1,path1[maxn][2],path2[maxn][2],dis[maxn][2],vis[maxn][2];
struct Edge{
int v,w,next;
}e[maxm];
void addedge(int u,int v,int w){
e[ee]=Edge{v,w,h[u]};
h[u]=ee++;
}
struct Node{
int id,op,d;
bool operator<(const Node a)const{
return d<a.d;
}
};
queue<int>q;
void bfs(int u){
memset(dis,0x3f,sizeof(dis));
dis[u][0]=dis[u][1]=0;
q.push(u);
while(!q.empty()){
int u=q.front();q.pop();
for(register int i=h[u];i;i=e[i].next){
int v=e[i].v,w=e[i].w;
if(dis[v][w]>max(dis[u][0],dis[u][1])+1){
dis[v][w]=max(dis[u][0],dis[u][1])+1;
path1[v][w]=u;
if(dis[u][1]>dis[u][0])path2[v][w]=1;else path2[v][w]=0;
q.push(v);
}
}
}
}
int main(){
int n=rd(),m=rd();
while(m--){
int u=rd(),v=rd(),w=rd();
addedge(v,u,w);
}
bfs(n);
if(dis[1][0]>inf/4 || dis[1][1]>inf/4){
wrn(-1);
}else wrn(max(dis[1][0],dis[1][1]));
FOR(i,1,n+1){
if(dis[i][0]>dis[i][1])printf("0");else printf("1");
}
puts("");
}