acm-(最短路、有向图、思维)Codeforces Round #669 (Div. 2) E. Egor in the Republic of Dagestan

24 篇文章 0 订阅
14 篇文章 0 订阅

题面
传送门
本题让给出一个状态分配方案使得从 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("");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值