计蒜客-百度地图导航
题意:中文题意;
解题思路:这道题麻烦就在于城市群这个东西,所以我们首先就得解决掉这个,最开始思路(建立虚拟源点和汇点,然后有1的城市群和有5的城市群分别连,然后就发现了连样例都对不上,正好发现了如果s,t在同一群内,会造成城市群内的点任意到达这种情况),明显需要拆点,将一个城市群拆成两个点,一个入点,一个出点,如果两个城市群之间有路径,那么x出连接y入,y出连接x入,城市群内的点分别与出点连接权值为0的边,入点分别与群内的点连接一个边权为0的边;
实际上就是我们对城市群处理一下,因为暴力建边不行,我们只能想办法将两个城市群连接起来,那么建立每个城市群建立两个虚拟的城市群源汇点就行了;这样,通过这两个点可以让两个城市群相连。
记得long long 和无解的情况;
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 1000500
#define ll long long
const ll inf=1e15;
using namespace std;
struct node
{
ll num;
ll dist;
node(ll _num=0,ll _dist=0):num(_num),dist(_dist){}
friend bool operator<(node a,node b)
{
return a.dist>b.dist;
}
};
struct Edge
{
ll next;
ll to;
ll w;
}edge[maxn];
ll n,m,k,m1,m2,x,y,w,q;
ll s,t;
ll head[maxn];
ll cnt;
ll dist[maxn];
void add(ll u,ll v,ll w)
{
edge[cnt].next=head[u];
edge[cnt].to=v;
edge[cnt].w=w;
head[u]=cnt++;
}
void dij(ll u)
{
for(ll i=1;i<=maxn;i++)
dist[i]=inf;
dist[u]=0;
priority_queue<node>q;
q.push(node(u,dist[u]));
while(!q.empty())
{
node now=q.top();q.pop();
ll x=now.num;
for(ll i=head[x];i!=-1;i=edge[i].next)
{
ll v=edge[i].to;
if(dist[v]>dist[x]+edge[i].w)
{
dist[v]=dist[x]+edge[i].w;
q.push(node(v,dist[v]));
}
}
}
}
int main()
{
scanf("%lld%lld",&n,&m);memset(head,-1,sizeof(head));cnt=0;
for(ll i=1;i<=m;i++)
{
scanf("%lld",&k);
for(ll j=1;j<=k;j++)
{
scanf("%lld",&q);
add(n+i,q,0);
add(q,n+n+i,0);
}
}
scanf("%lld",&m1);
for(ll i=1;i<=m1;i++)
{
scanf("%lld%lld%lld",&x,&y,&w);
add(x,y,w);add(y,x,w);
}
scanf("%lld",&m2);
for(ll i=1;i<=m2;i++)
{
scanf("%lld%lld%lld",&x,&y,&w);
add(n+n+x,n+y,w);
add(n+n+y,n+x,w);
}
scanf("%lld%lld",&s,&t);
dij(s);
if(dist[t]==inf)
printf("-1\n");
else
printf("%lld\n",dist[t]);
}

浙公网安备 33010602011771号