题意:给n个点m条边的图,每条边有等级,不能连续走两条等级相同的边,求s到t的最短路。
解法:最短路的变形,用二维的spfa,dist[i][j]表示经过等级为j的边到点i的最短路。但初始化的时候要注意是把dist[s][0]放进队列。
//time 29ms #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; #define maxn 105 #define maxm 50005 #define inf 1<<30 int n,m,k,Q; struct node { int v,w,next,p; }e[maxm]; int ecnt,pre[maxn]; int dis[maxn][maxn]; bool vis[maxn][maxn]; void addEdge(int u,int v,int w,int p) { e[ecnt].v=v; e[ecnt].w=w; e[ecnt].p=p; e[ecnt].next=pre[u]; pre[u]=ecnt++; } struct Node{ int u,p; }; void spfa(int s,int t) { queue<Node> q; Node tmp; memset(vis,0,sizeof(vis)); for (int i=1;i<=n;i++) for (int j=1;j<=k;j++) dis[i][j]=inf; tmp.u=s; tmp.p=0; q.push(tmp); dis[s][0]=0; while (!q.empty()) { int u=q.front().u,p=q.front().p; q.pop(); vis[u][p]=0; for (int i=pre[u];i!=-1;i=e[i].next) { int v=e[i].v,pp=e[i].p,w=e[i].w; if (pp!=p&&dis[v][pp]>dis[u][p]+w) { dis[v][pp]=dis[u][p]+w; if (!vis[v][pp]) { tmp.u=v; tmp.p=pp; q.push(tmp); vis[v][pp]=1; } } } } int ans=inf; for (int i=1;i<=k;i++) ans=min(dis[t][i],ans); if (ans==inf) printf("infinity\n"); else printf("%d\n",ans); } int main() { //freopen("/home/moor/Code/input","r",stdin); int s,t,cas,u,v,p,w; scanf("%d",&cas); while (cas--) { scanf("%d%d%d%d",&n,&m,&k,&Q); ecnt=0; memset(pre,-1,sizeof(pre)); for (int i=1;i<=m;i++) { scanf("%d%d%d%d",&u,&v,&w,&p); addEdge(u,v,w,p); addEdge(v,u,w,p); } while (Q--) { scanf("%d%d",&s,&t); if (s==t) printf("0\n"); else spfa(s,t); } } return 0; }