SGU103

来源:互联网 发布:淘宝直播合作平台 编辑:程序博客网 时间:2024/05/02 00:44

题目大意:

给定一个带权无向图,每个点有一个颜色属性,要么为Blue要么为Purple,颜色会在B和P之间来回变换,两种颜色各有一个持续时间

两个邻接的点之间能够通行当且仅当两点是相同的颜色,通行的代价为边权,可在点处等待

给定起点,终点,每个点的初始颜色和持续时间,蓝色的持续时间,紫色的持续时间

求起点到终点的最短时间


如果没有颜色通行的限制,那么这道题就是个最短路,加上了颜色的通行限制,题目似乎就变了

最短路的性质是s-t的最短路如果经过了k,那么s-k也一定是一条最短路

但这道题似乎有可能存在这种情况,由于颜色限制,s-k不是最短路,但k-t是最短路

更仔细一点想,这种情况是不存在的

如果s-k不是最短路,其代价为d,那么我们可以求出s-k的最短路,其代价为d'

问题在于有可能k-t存在等待时间,显然s-k的最短路可以不会比非次短路差

所以求一遍s-t的最短路即可,SPFA和Dijkstra都行


关于等待时间:

a-b的等待时间和到达a的时间有关系,而松弛的条件是dis[v]>dis[x]+边权+等待时间

因此设计一个wait函数即可(这里比较蛋疼……我wa2无数遍就是因为打错一变量)

//Lib#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<ctime>#include<iostream>#include<algorithm>#include<vector>#include<string>#include<queue>using namespace std;//Macro#define rep(i,a,b) for(int i=a,ttmp=b;i<=ttmp;i++)#define rrep(i,a,b) for(int i=a,ttmp=b;i>=ttmp;i--)#define erep(i,e,x) for(int i=x;i;i=e[i].next)#define irep(i,x) for(__typedef(x.begin()) i=x.begin();i!=x.end();i++)#define read() (strtol(ipos,&ipos,10))#define sqr(x) ((x)*(x))#define pb push_back#define PS system("pause");typedef long long ll;typedef pair<int,int> pii;const int oo=~0U>>1;const double inf=1e20;const double eps=1e-6;string name="",in=".in",out=".out";//Varpriority_queue<pii,vector<pii>,greater<pii> > q;struct N{int re,b,l;}node[308];struct E{int next,node,v;}e[30008];int tot,st,ed,n,m;int h[308],dis[308],pre[308];bool vis[308];void add(int a,int b,int c){e[++tot].next=h[a];e[tot].node=b;e[tot].v=c;h[a]=tot;}void Init(){int a,b,c;char ch[5];scanf("%d%d",&st,&ed);if(st==ed){cout<<0<<endl<<st<<endl;exit(0);}scanf("%d%d",&n,&m);rep(i,1,n){scanf("%s %d %d %d",ch,&a,&b,&c);if(ch[0]=='P')node[i].re=b+c-a;else node[i].re=b-a;//将起始颜色转化为B,re代表到下一种颜色的时间node[i].b=b;node[i].l=b+c;//b代表blue的时间,l代表周期}rep(i,1,m){scanf("%d%d%d",&a,&b,&c);add(a,b,c);add(b,a,c);}}int wait(int x,int y,int t){int tx,ty,tmp,ret;tx=(t+node[x].re)%node[x].l;ty=(t+node[y].re)%node[y].l;ret=0;rep(i,1,4){if((tx<node[x].b)==(ty<node[y].b))return ret;if(tx<node[x].b)tmp=node[x].b-tx;else tmp=node[x].l-tx;if(ty<node[y].b)tmp=min(tmp,node[y].b-ty);elsetmp=min(tmp,node[y].l-ty);ret+=tmp;tx=(tx+tmp)%node[x].l;ty=(ty+tmp)%node[y].l;}return -1;}void Print(int x){if(pre[x])Print(pre[x]);printf("%d ",x);}void Work(){rep(i,1,n)dis[i]=oo;int x,y,t;dis[st]=0;q.push(pii(0,st));while(!q.empty()&&!vis[ed]){x=q.top().second;q.pop();if(vis[x])continue;vis[x]=true;erep(i,e,h[x]){y=e[i].node;t=wait(x,y,dis[x]);if(t>=0&&dis[y]>dis[x]+t+e[i].v){dis[y]=dis[x]+t+e[i].v;pre[y]=x;q.push(pii(dis[y],y));}}}if(dis[ed]==oo)printf("0\n");else{printf("%d\n",dis[ed]);Print(pre[ed]);printf("%d\n",ed);}}int main(){//freopen((name+in).c_str(),"r",stdin);//freopen((name+out).c_str(),"w",stdout);Init();Work();return 0;}



原创粉丝点击