伊吹萃香_(虫洞)

筅森魡賤 提交于 2020-02-05 12:02:00

网上竟然没有能看的懂的解释,我也是醉了
搞了好几个小时才找着一份代码,硬是看懂了
思路:记一个dis[i][j]数组,i表示节点,j表示时间是奇数还是偶数,0是偶数,1是奇数
某一个点的状态是由上一秒转移来的,而这两秒一定一个是奇数一个是偶数,所以1状态由0转移,0状态由1转移,黑洞需要翻转,而奇数秒的状态一定是被反转了的,偶数是没反转的,而这个可以用异或来搞定
因为0^1=1,1^1==0
而判断起点也是用异或
如果起点是白洞,偶数次之后还是白洞,奇数次后变成了黑洞,因为0^0=0,0^1=1,1^0=1,1^1=0

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
#include<iostream>#include<cstring>#include<cstdio>#include<queue>#include<cmath>using names 大专栏  伊吹萃香_(虫洞)pace std;struct st{	int s;	bool f;};int n,m;int vis[19999][2],dis[19999][2],head[1999],nex[19999],cost[19999],to[199999],w[19999],tot,col[199999],s[19999];deque <st> q;void add(int x,int y,int z){	tot++;	nex[tot]=head[x];	to[tot]=y;	cost[tot]=z;	head[x]=tot;} int dist(int stt,int too,bool ff)//判断起点{	int sf=col[stt]^ff;	int tf=col[too]^ff;	int ww=abs(w[stt]-w[too]);	if(sf==tf)return 0;	if(sf==1) return ww;	else return -ww;}void spfa(int ss){	dis[ss][0]=0;    vis[ss][0]=1;    q.push_back((st){ss,0});	while(!q.empty())	{		st o=q.front();q.pop_front();		int x=o.s;		vis[x][o.f]=0;		for(int i=head[x];i;i=nex[i])		{			int tmp=to[i];			if(dis[tmp][o.f^1]>dis[x][o.f]+max(cost[i]+dist(x,tmp,o.f),0))			{				dis[tmp][o.f^1]=dis[x][o.f]+max(cost[i]+dist(x,tmp,o.f),0);				if(!vis[tmp][o.f^1])				{					if(dis[tmp][o.f^1]<=dis[q.front().s][q.front().f])					q.push_front((st){tmp,o.f^1});					else q.push_back((st){tmp,o.f^1});					vis[tmp][o.f^1]=1;				}			}		}		if(dis[x][o.f^1]>dis[x][o.f]+(col[x]^o.f)*s[x])		{			dis[x][o.f^1]=dis[x][o.f]+(col[x]^o.f)*s[x];			if(!vis[x][o.f^1])			{				if(dis[x][o.f^1]<=dis[q.front().s][q.front().f])				q.push_front((st){x,o.f^1});				else q.push_back((st){x,o.f^1});				vis[x][o.f^1]=1;			}		}	}}int main(){	memset(dis,127,sizeof dis);	scanf("%d%d",&n,&m);	for(int i=1;i<=n;i++)	scanf("%d",&col[i]);	for(int i=1;i<=n;i++)	scanf("%d",&w[i]);	for(int i=1;i<=n;i++)	scanf("%d",&s[i]);	for(int i=1;i<=m;i++)	{		int x,y,z;		scanf("%d%d%d",&x,&y,&z);		add(x,y,z);	}	spfa(1);	printf("%d",min(dis[n][0],dis[n][1]));}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!