伊吹萃香

来源:互联网 发布:淘宝已好评怎么修改 编辑:程序博客网 时间:2024/06/04 08:36

网上竟然没有能看的懂的解释,我也是醉了
搞了好几个小时才找着一份代码,硬是看懂了
思路:记一个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

#include<iostream>#include<cstring>#include<cstdio>#include<queue>#include<cmath>using namespace 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]));}