SGU 103 – Shortest Path Variant

/* Shortest Path Vairant
 * Don't be scared!!!
 * Greedy strategy is still applied.
 * Just do it!
 */
 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
 
int  g[305][305],it[305],bt[305],pt[305],d[305],p[305];
int  src,dst,n,m;
bool used[305];
char ic[305];
 
void Current(int nowT, int at, char &fromC, int &remC)
{
	if(nowT<it[at]) {
		fromC=ic[at];
		remC=it[at]-nowT;
	} else {
		nowT-=it[at];
		nowT%=(bt[at]+pt[at]);
		if(ic[at]=='P') {	//Careful!
			if(nowT<bt[at]) {
				fromC='B'; remC=bt[at]-nowT;
			} else {
				fromC='P'; remC=pt[at]-(nowT-bt[at]);
			}
		} else {
			if(nowT<pt[at]) {
				fromC='P'; remC=pt[at]-nowT;
			} else {
				fromC='B'; remC=bt[at]-(nowT-pt[at]);
			}
		}
	}
}
 
int calWait(int nowT, int from, int to)
{
	char fromC,toC;
	int  fromR,toR,nextFT,nextTT,nnextFT,nnextTT;
	//printf("!!%d %d %d = %d\n",nowT,from,to);
	Current(nowT,from,fromC,fromR);
	//printf("--CurrentF %d %d %c %d\n",nowT,from,fromC,fromR);
	Current(nowT,to,toC,toR);
	//printf("--CurrentT %d %d %c %d\n",nowT,to,toC,toR);
	//printf("--%d %d %d %d\n",fromC, toC, fromR, toR);
	if(fromC==toC) return 0;
	else {
		if(fromR<toR) return fromR;
		else if(fromR>toR) return toR;
		else {
			if(fromC=='B') nextFT=pt[from]; else nextFT=bt[from];
			if(fromC=='B') nnextFT=bt[from]; else nnextFT=pt[from];
			if(toC=='B') nextTT=pt[to]; else nextTT=bt[to];
			if(toC=='B') nnextTT=bt[to]; else nnextTT=pt[to];
			if(nextTT+nnextTT==nextFT+nnextFT) return -1;
			if(nextTT==nextFT) return fromR+nextFT+min(nnextFT,nnextTT);
			else return fromR+min(nextFT,nextTT);			
		}
	}
}
 
void print(int x)
{
	if(p[x]!=x) print(p[x]);
	printf("%d ",x);
}
int main()
{
	char str[100];
	int u,v,w;
	scanf("%d %d",&src,&dst);
	scanf("%d %d",&n,&m); gets(str);
	for(int i=1;i<=n;i++)
	{
		scanf("%s %d %d %d",str,&it[i],&bt[i],&pt[i]);
		ic[i]=str[0];		
	}
 
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d %d",&u,&v,&w);
		g[u][v]=g[v][u]=w;
	}
 
	memset(used,0,sizeof(used));
	for(int i=1;i<=n;i++) d[i]=1<<29;
	d[src]=0; p[src]=src;
	for(int cc=1;cc<n;cc++)
	{
		int md=1<<29,mp=0;
		for(int i=1;i<=n;i++)
			if(!used[i]&&d[i]<md) { md=d[i]; mp=i; }
		if(!mp) break; else used[mp]=true;
		for(int i=1;i<=n;i++) if(!used[i]&&g[mp][i])
		{
			int wait=calWait(d[mp],mp,i);
			//printf("wait=%d\n",wait);
			if(wait<0) continue;
			if(d[i]>wait+d[mp]+g[mp][i]) {
				d[i]=wait+d[mp]+g[mp][i];
				p[i]=mp;
			}
		}
	}
	//for(int i=1;i<=n;i++) printf("%d ",d[i]); printf("\n");
	if(d[dst]<(1<<29)) printf("%d\n",d[dst]);
	print(dst);
	return 0;
}

Leave a Reply

Your email address will not be published.