sgu103

来源:互联网 发布:淘宝订单险坑卖家钱 编辑:程序博客网 时间:2024/05/22 11:45
</pre><div>题目大意</div><div>给出一个N个结点的无向图,每条边都有一个长度,但是每条边的两端有信号灯。信号灯有两种颜色:蓝色和紫色,并且信号灯有颜色变化的周期。当要走这条路,这条路的两端</div><div>颜色一样时,才可以走,否则需要等到其中一个等变色后再走(<span style="color: rgb(255, 0, 0);">走这条路的中途不用管灯的颜色</span>)。给定两个点st,ed,求从st到ed最少的时间是多少。</div><div></div><div>我们要注意如果正好在变灯的时间点要按照变了灯算。。。还是最短路,在某个点的时候走过去的花费是在边权(灯一样)or边权+等待(灯不一样等到一样)</div><div>要注意处理一种情况就是两边的灯互相变换,周期相等,这种情况这条路是走不了的</div><div></div><div>不管怎样还是个最短路,spfa也好 dijk也好。。。哪个顺手写那个吧。。。就酱紫。。。</div><div></div><div><pre name="code" class="cpp">#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;const int maxn = 501;const int maxm = 15000;const int inf = 99999999;int s , t;int n , m;int C[maxn] , riC[maxn] , tiB[maxn] , tiP[maxn] ;int pre[maxm] , other[maxm] , last[maxn] , len[maxm];int visit[maxn];int l = 0;int dist[maxn] , lastx[maxn] , que[maxm*10] , ans[maxn];int add_edge(int x,int y, int z){pre[++l] = last[x] ; last[x] = l ; other[l] = y ; len[l] = z ;pre[++l] = last[y] ; last[y] = l ; other[l] = x ; len[l] = z ;}int prepare(){scanf("%d%d", &s , &t);getchar();scanf("%d%d", &n , &m);getchar();for (int i = 1 ; i <= n ; i ++){char color;scanf("%c%d%d%d",&color,&riC[i],&tiB[i],&tiP[i]);getchar();if (color == 'B') C[i] = 0;else C[i] = 1;}//cout <<"!"<<endl;for (int i = 1 ; i <= m ; i ++){int p , q, r ;scanf("%d%d%d",&p,&q,&r);add_edge(p,q,r);}}void color ( int nowx , int nowtime , int &ca ,int &ta ){if ( nowtime < riC[nowx] ) {ta = riC[nowx] ; ca = C[nowx];return ;}else {int temp = ( nowtime - riC[nowx] ) % ( tiB[nowx] + tiP[nowx] );int now = nowtime - temp ;if ( C[nowx] == 1 ) {if ( temp < tiB[nowx]) {ca = 0 ; ta = now + tiB[nowx];return ;}else {ca = 1 ; ta = now + tiB[nowx] + tiP[nowx] ;return ;}}else{if ( temp < tiP[nowx] ){ca = 1 ;ta = now + tiP[nowx];return ;}else {ca = 0 ;ta = now + tiB[nowx] + tiP[nowx] ; return ;}}}}int deal(int nowx ,int nowp , int nowtime ,int f){int ca , cb , ta , tb ;int nowy = other[nowp];color ( nowx , nowtime , ca , ta );color ( nowy , nowtime , cb , tb );if (ca == cb ) return nowtime ; if (ta == tb ){if ( f == 0 ) return deal(nowx , nowp , ta , 1) ;else if (nowtime <= riC[nowx] || nowtime <= riC[nowy]) return deal(nowx , nowp , ta , 1);else return inf ;}return min(ta , tb);}void spfa(){int l = 0 , r = 1;memset( visit , 0 , sizeof( visit ));for ( int i = 0 ; i <= t ; i ++ ) dist[i] = inf ;que[1] = s ; visit[s] = 1; dist[s] = 0;lastx[s] = 0;while ( l != r ){int x = que[++l];for (int p = last[x] ; p != 0; p = pre[p]){int now = deal( x, p , dist[x] ,0);if ( now >= inf ) break;if ( len[p] + now < dist[other[p]] ) {dist[other[p]] = len[p] + now;lastx[other[p]] = x ;if ( !visit[other[p]] ){visit[other[p]] = 1 ;que[++r] = other[p] ;}}}visit[x] = 0 ;}if ( dist[t] >= inf ) {cout << "0" << endl;return ;}cout << dist[t] <<endl;int fw = t , leng = 0 ;while ( fw ) {ans[++leng] = fw ; fw = lastx[fw];}for (int i = leng ; i > 1 ; i --){printf("%d ", ans[i]);}printf("%d\n",ans[1]);return ;}int main(){prepare();spfa();}


0 0