UVA1599 理想路径 Ideal Path(最短路径)

题目链接

满分做法:

在做搜索 最短路路径时 可以从终点搜到起点,记录该位置到终点的最短路,再次搜索时从起点搜索并判断即可。

本题还要比较颜色的字典序,于是我们把当前深度的点都拿出来,进行向外扩展,找到既在最短路径上,又经过颜色字典序最小的点,加入到队列中,并把当前颜色最小值加入到答案序列即可。

#include<queue>
#include<cmath>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxm=4e5+7;
int n,m;
int pre[maxm],last[100007],other[maxm],len[maxm],l;
int dis[100007];
bool vis[100007];
vector<int > ans;
void add(int x,int y,int z)
{
 l++;
 pre[l]=last[x];
 last[x]=l;
 other[l]=y;
 len[l]=z;	
}
void bfs()//反向找最短路,便于第二次bfs找到最短路径 
{
 dis[n]=0;
 queue<int >q;
 q.push(n);
 while(q.size())
 {
   int u=q.front();
   q.pop();
   for(int p=last[u];p;p=pre[p])
   {
    int v=other[p];
    if(dis[v]!=-1) continue;
    dis[v]=dis[u]+1;
    q.push(v);
   }
 }	
}
void bfs1()
{
 queue<int > q;
 q.push(1);
 vis[1]=1;
 while(q.size())
 { 
   vector<int> c;
   while(q.size())
   {
   	 c.push_back(q.front());
   	 q.pop();
   }
   int minn=1e9+7;
   for(int i=0;i<c.size();i++)
   {
   	 int u=c[i];
   	 for(int p=last[u];p;p=pre[p])
   	 {
   	 	int v=other[p];
   	    if(dis[v]+1==dis[u])
		{
		  minn=min(minn,len[p]);
	    }
   	 }
   }
   if(minn==1e9+7) return;//扩展完全
   ans.push_back(minn);
   for(int i=0;i<c.size();i++)
   {
     int u=c[i];
	 for(int p=last[u];p;p=pre[p])
	 {
	  int v=other[p];
	  if(dis[v]+1==dis[u]&&len[p]==minn&&!vis[v])
	  {
	  	vis[v]=1;
	  	q.push(v);
	  }
     }
   }
 }	
}
int main()
{
 while(scanf("%d%d",&n,&m)==2)
 {
  memset(dis,-1,sizeof(dis));
  memset(vis,0,sizeof(vis));
  memset(last,0,sizeof(last));
  l=0;
  ans.clear();
  for(int i=1;i<=m;i++)
  {
   int x,y,z;
   scanf("%d%d%d",&x,&y,&z);
   add(x,y,z);
   add(y,x,z);	
  }
  bfs();
  bfs1();
  printf("%d
",ans.size());
  for(int i=0;i<ans.size();i++)
  printf("%d%c",ans[i],i+1==(int)ans.size()?'
':' ');
 }
 return 0;	
}
原文地址:https://www.cnblogs.com/lihan123/p/11771983.html