首页 > 代码库 > SGU515:Recover path 【最短路】

SGU515:Recover path 【最短路】

警告:这题卡SPFA,警告:这题卡SPFA 这不是演习

题目大意:给出一个无向图,以及一些点的序列,要找出一条最短的路径使得通过所有点,题目保证存在一条头尾都在点的序列中的最短路满足题意

思路:没有最后那个保证应该就是神题了TUT 有的话显然最后的答案是一条链,而我们要做的便是找出这条链的头尾,随便找个序列中的点跑下最短路,那么头或尾两个点离这个点一定是最远的!找到一个端点后接下来便是DP找下一个端点,记忆化搜索使得路径上包含的序列点数最多,由于题目保证存在方案,最后这条路径一定是答案

最后。。。。这题卡SPFA 这不是演习

 

  1 #include <stdio.h>  2 #include <iostream>  3 #include<queue>  4 #include <string.h>  5 #include <algorithm>  6 #define maxn 200009  7 using namespace std;  8 typedef pair<int,int>pii;  9 int head[maxn],next[maxn],point[maxn],value[maxn],now=0; 10 int n,m,maxx=-1,po,dist[maxn],x,y,z,k,v[maxn],dp[maxn],egz[maxn]; 11 int an=0,pp[maxn],final[maxn],oo=0; 12 int num[maxn],route[maxn]; 13  14 void add(int x,int y,int v,int zz) 15 { 16     next[++now]=head[x]; 17     head[x]=now; 18     point[now]=y; 19     value[now]=v; 20     num[now]=zz; 21 } 22 struct cmp 23 { 24     bool operator()(pii a,pii b) 25     { 26         return a.first>b.first; 27     } 28 }; 29 void dijkstra(int s) 30 { 31     memset(dist,-1,sizeof(dist)); 32     dist[s]=0; 33     priority_queue<pii,vector<pii>,cmp>q; 34     q.push(make_pair(0,s)); 35     while(!q.empty()) 36     { 37         pii u=q.top(); 38         q.pop(); 39         if(u.first>dist[u.second])continue; 40         for(int i=head[u.second];i!=0;i=next[i]) 41         { 42             int k=point[i]; 43             if(dist[u.second]+value[i]<dist[k] || dist[k]==-1) 44             { 45                 dist[k]=dist[u.second]+value[i]; 46                 q.push(make_pair(dist[k],k)); 47             } 48         } 49     } 50 } 51 /* 52 void spfa(int s,int o) 53 { 54     int visit[maxn]={0}; 55     queue<int>q; 56     for(int i=1;i<=n;i++)dist[i]=-1; 57     dist[s]=0; 58     visit[s]=1; 59     q.push(s); 60     while(!q.empty()) 61     { 62         int u=q.front(); 63         q.pop(); 64         visit[u]=0; 65         for(int i=head[u];i!=0;i=next[i]) 66         { 67             int k=point[i]; 68             if(dist[u]+value[i]<dist[k]|| dist[k]==-1) 69             { 70                 dist[k]=dist[u]+value[i]; 71                 if(visit[k]==0) 72                 { 73                     visit[k]=1; 74                     q.push(k); 75                 } 76             } 77         } 78     } 79 } 80 */ 81 int dfs(int s,int b) 82 { 83     if(dp[s]!=-1)return dp[s]; 84     int ans=0; 85     for(int i=head[s];i!=0;i=next[i]) 86     { 87         int u=point[i]; 88         if(dist[u]!=dist[s]+value[i])continue; 89         int val=dfs(u,(egz[s]?b+1:b)); 90         if(val>ans) 91         { 92             ans=val; 93             pp[s]=u; 94             route[s]=num[i]; 95             if(val==k-1)break; 96         } 97     } 98     return dp[s]=ans+(egz[s]==1?1:0); 99 }100 int main()101 {102     scanf("%d%d",&n,&m);103     for(int i=1;i<=m;i++)104     {105         scanf("%d%d%d",&x,&y,&z);106         add(x,y,z,i);107         add(y,x,z,i);108     }109     scanf("%d",&k);110     for(int i=1;i<=k;i++){scanf("%d",&v[i]);egz[v[i]]=1;}111     dijkstra(v[1]);112     for(int i=1;i<=k;i++)if(dist[v[i]]>maxx)113     {114         maxx=dist[v[i]];115         po=v[i];116     }117     dijkstra(po);118     memset(dp,-1,sizeof(dp));119     dfs(po,1);120     an=po;121     while(pp[an]!=0)122     {123         final[++oo]=route[an];124         an=pp[an];125     }126     printf("%d\n",oo);127     for(int i=1;i<=oo-1;i++)printf("%d ",final[i]);128     printf("%d",final[oo]);129     return 0;130 }

 

SGU515:Recover path 【最短路】