您的位置:首页 > 其它

路数有限制(w的倍数)的最短路,【二维dijkstra】 双重限制并输出路径和方法数

2016-03-31 12:07 399 查看
比一般的dijkstra数组多了一维。

#include<iostream>
#include<algorithm>
#include<map>//ll dx[4]={0,0,-1,1};ll dy[4]={-1,1,0,0};
#include<set>//
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#include<string>
#define mod 1000000007
#define ll long long
#define inf 10000000000000
#define lowbit(x) (x) & (-x)
using namespace std;
ll x[102][102];
ll d[102][12];   //记录i点在路数%w=j时的最短路程
int v[102][12];   //判断i点有没有出现过路数%w=j的状态
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
x[i][j]=inf;
}
}
while(m--){
int a,b;
ll c;
scanf("%d%d%lld",&a,&b,&c);
x[a][b]=min(x[a][b],c);
}
int st,ed,w;
scanf("%d%d%d",&st,&ed,&w);
for(int i=0;i<n;++i){
for(int j=0;j<w;++j){
d[i][j]=inf;
v[i][j]=0;
}
}
d[st][0]=0;
while(1){ //本来这里是for(int i=0;i<n;++i)
ll get=inf;
ll idx=-1,num=-1;
for(int i=0;i<n;++i){
for(int j=0;j<w;++j){
if(v[i][j]==0&&d[i][j]<get){
get=d[i][j];
idx=i;
num=j;
}
}
}
if(idx==-1||(idx==ed&&num==0)) //当前已经无法拓新或者已经找到了终点是w倍数的情况,直接退出
break;
v[idx][num]=1;
for(int i=0;i<n;++i){
if(x[idx][i]==inf||v[i][(num+1)%w]==1) continue;
d[i][(num+1)%w]=min(d[i][(num+1)%w],d[idx][num]+x[idx][i]);
}
}
if(d[ed][0]==inf)
printf("No Answer!\n");
else
printf("%lld\n",d[ed][0]);
}
return 0;
}
https://www.patest.cn/contests/gplt/L2-001

小坑,钻了两个小时。头晕。前向星和优先队列写法规范。
#include<bits/stdc++.h>
#define ll long long
using namespace std; //
struct EDGE{
int u,v,w,next;
}edge[500*500*2+5];
int head[500*500+5],pp;
void init(){
pp=0;
memset(head,0,sizeof(head));
}
void add(int u,int v,int w){
edge[++pp]=(EDGE){u,v,w,head[u]};
head[u]=pp;
}
int n,m,a,b,c,d,e;
int x[505];
int vis[505];
int dis[505];
int cost[505];
int path[505];
int times[505];
struct cmp{
bool operator()(const int &t1,const int &t2){
if(dis[t1]!=dis[t2])
return dis[t1]>dis[t2];
return cost[t1]<cost[t2];
}
};
int main(){
cin>>n>>m>>a>>b;
init();
for(int i=0;i<n;++i)
cin>>x[i];
while(m--){
cin>>c>>d>>e;
add(c,d,e);
add(d,c,e);
}
for(int i=0;i<n;++i)
dis[i]=100000000;
priority_queue<int,vector<int>,cmp> q;
q.push(a);
dis[a]=0;
cost[a]=x[a];
times[a]=1;
while(!q.empty()){
int u=q.top();
q.pop();
if(vis[u]==1) continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
int w=edge[i].w;
if(vis[v]==1) continue;
if(dis[u]+w<dis[v]) times[v]=times[u];
else if(dis[u]+w==dis[v]) times[v]+=times[u];
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
cost[v]=cost[u]+x[v];
q.push(v);
path[v]=u;
}
else if(dis[u]+w==dis[v]&&cost[u]+x[v]>cost[v]){
cost[v]=cost[u]+x[v];
q.push(v);
path[v]=u;
}
}
}
cout<<times[b]<<" "<<cost[b]<<endl;
stack<int> st;
int tmp=b;
while(path[b]!=a){
st.push(path[b]);
b=path[b];
}
cout<<a;
while(!st.empty()){
cout<<" "<<st.top();
st.pop();
}
if(b!=a)
cout<<" "<<tmp;
cout<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: