P5764 [CQOI2005]新年好

题目

题目

思路

stoorz&QuantAsk&my_dog&myd&Velix:这不是有手就行


真没发现那里有手就行……
第一个反应是Floyd,但是看数据范围n<=50000,凉凉。
接下来我们发现,在求最短路这方面,可以使用dij+堆优化+离散化完成,即只对给定的6个点进行dij。
接下来dfs枚举顺序,AC。
code:

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int b[6][50001],e=1,first[50001],pu[6];
struct f{
    
    
 int b;
 int d;
 int net;
} a[200002];
bool book[50001];
struct f2{
    
    
 int x,y;
} p;
bool operator <(const f2 &x,const f2 &y)
{
    
    
 return x.x>y.x;
}
priority_queue<f2> c[6];
void jb(int x,int y,int z)
{
    
    
 a[e].b=y;
 a[e].d=z;
 a[e].net=first[x];
 first[x]=e;
 e++;
 return;
}
int ans=0x7fffffff;
void dfs(int x,int s,int y)
{
    
    
 if (s>ans) return;
 if (x==5)
 {
    
    
  ans=s;
  return;
 }
 for (int i=5;i>=1;i--)
 {
    
    
  if (!book[i])
  {
    
    
   book[i]=1;
   dfs(x+1,s+b[y][pu[i]],i);
   book[i]=0;
  }
 }
 return;
}
int main()
{
    
    
 int n,m,q;
 cin>>n>>m;
 pu[0]=1;
 for (int i=1;i<6;i++) cin>>pu[i];
 int x,y,z;
 for (int i=1;i<=m;i++)
 {
    
    
  cin>>x>>y>>z;
  if (x==y) continue;
  jb(x,y,z);
  jb(y,x,z); 
 }
 for (int j=0;j<6;j++)
 {
    
    
  q=pu[j];
  for (int i=1;i<=n;i++) b[j][i]=0x7fffffff,book[i]=0;
  b[j][q]=0;
  p.x=0,p.y=q;
  c[j].push(p);
  while (c[j].size())
  {
    
    
   int u=c[j].top().y;
   c[j].pop();
   if (book[u]) continue;
   book[u]=1;
   for(int i=first[u];i!=0;i=a[i].net)
   {
    
    
    if(a[i].d+b[j][u]<b[j][a[i].b])
    {
    
    
     b[j][a[i].b]=a[i].d+b[j][u];
     p.x=b[j][a[i].b];
     p.y=a[i].b;
     c[j].push(p);
    }
   }
  }
 }
 for (int i=0;i<=10;i++) book[i]=0;
 dfs(0,0,0);
 cout<<ans;
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/114270631