SPFA过的。
虽然很麻烦,其实就是加上一个限制条件的最短路。
题意是说给你一些点,一些边,起点与终点。
然后这些边通过的时候需要花费时间,但是也有开关限制。
问你到达重点的最短路。(无向图)
比如输入:
1 2 6 2 10 22 30
表示 1 -> 2 需要花费时间为 6。
0~1 , 1~2 , 2~3 , 3~4 , 4~5
0~2 打开,2~10关闭,10~22打开,22~30关闭,33~INF打开。
我存下开关状态的时候 多存一个 0 和一个 INF。方便判断。
判断小于第奇数个数时打开,偶数关闭。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<queue> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 using namespace std; int n,m; struct lx { int v,w; vector<int>open; }; vector<lx> g[51]; void SPFA(int start,int thend) { int dis[51]; bool vis[51]; for(int i=1; i<=n; i++) dis[i]=INF,vis[i]=0; queue<int>q; dis[start]=0,vis[start]=1; q.push(start); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int j=0; j<g[u].size(); j++) { int v=g[u][j].v; int t=g[u][j].w; int cot=g[u][j].open.size(); bool openflag=1; int k; for( k=1; k<cot; k++) { if(k&1)openflag=1; else openflag=0; if(openflag&&dis[u]+t<=g[u][j].open[k]&&t+g[u][j].open[k-1]<=g[u][j].open[k]) { int wait=g[u][j].open[k-1]; int cost=max(wait,dis[u]); if(openflag&&dis[v]>cost+t) { //printf("%d %d=%d\n",u,v,cost+t); 打印路径更新 dis[v]=cost+t; if(!vis[v]) { vis[v]=1; q.push(v); } } break; } } } } if(dis[thend]==INF)puts("*"); else printf("%d\n",dis[thend]); } int main() { while(scanf("%d",&n),n) { int start,thend; scanf("%d%d%d",&m,&start,&thend); for(int i=0; i<51; i++) g[i].clear(); int u,v,t; char str[1001]; int numtemp[1001]; getchar(); while(m--) { gets(str); int cc=0,numcot=0; for(int i=0; i<=strlen(str); i++) { if(str[i]>='0'&&str[i]<='9') cc=cc*10+str[i]-'0'; else numtemp[numcot++]=cc,cc=0; } u=numtemp[0],v=numtemp[1],t=numtemp[2]; lx now; now.w=t; now.open.push_back(0); for(int i=3; i<numcot; i++) now.open.push_back(numtemp[i]); now.open.push_back(INF); now.v=v; g[u].push_back(now); now.v=u; g[v].push_back(now); } /*for(int i=1;i<=n;i++) { for(int j=0;j<g[i].size();j++) { printf("%d %d==%d: ",i,g[i][j].v,g[i][j].w); for(int k=0;k<g[i][j].open.size();k++) printf("%d || ",g[i][j].open[k]); printf("\n"); } printf("\n\n"); }*/ // 存储方式 SPFA(start,thend); } }
POJ 1613 Cave Raider,布布扣,bubuko.com
原文:http://blog.csdn.net/dongshimou/article/details/36432379