点击跳转
把一个无向图连通分量看作一个点,然后形成一个 D A G DAG DAG,无向图分量之间用拓扑排序的方法更新,然后无向图内部使用 d i j k s t r a dijkstra dijkstra
d i j k s t r a dijkstra dijkstra的具体过程就是,把那些有值的点放进堆(有值就是说不为无穷),然后做正常的 d i j dij dij
这样为啥是对的呢,我觉得可以理解为有一个超级源,而这个超级源其实就对应原题的 S S S
#include
#include
#include
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
struct Graph
{
int etot, head[maxn], to[maxe], next[maxe], w[maxe];
void clear(int N)
{
for(int i=1;i<=N;i++)head[i]=0;
etot=0;
}
void adde(int a, int b, int c=0){to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;}
#define forp(_,__) for(auto p=__.head[_];p;p=__.next[p])
}G1, G2;
struct UnionFind
{
ll f[maxn], size[maxn];
void init(ll n)
{
for(auto i=1;i<=n;i++)f[i]=i, size[i]=1;
}
ll find(ll x){return f[x]==x?x:f[x]=find(f[x]);}
void merge(ll x, ll y)
{
auto fx=find(x), fy=find(y);
f[fx]=fy;
if(fx!=fy)size[fy]+=size[fx];
}
}uf;
ll indeg[maxn];
struct Dijkatra
{
ll dist[maxn];
priority_queue<pll,vector<pll>,greater<pll>> heap;
typedef pair<ll,ll> pr;
void init(ll N)
{
for(ll i=1;i<=N;i++)dist[i]=linf;
}
void run(Graph& G, vector<ll>& v)
{
for(auto x:v)heap.emplace(pr(dist[x],x));
while(!heap.empty())
{
pr x;
do x=heap.top(), heap.pop();
while(x.first!=dist[x.second] and !heap.empty());
for(auto p=G.head[x.second];p;p=G.next[p])
{
if(dist[G.to[p]] > dist[x.second]+G.w[p])
{
dist[G.to[p]] = dist[x.second]+G.w[p];
heap.emplace(pr(dist[G.to[p]],G.to[p]));
}
}
}
}
}dij;
vector<ll> lis[maxn];
int main()
{
ll n, x, y, S, i, u, v, w;
n=read(), x=read(), y=read(), S=read();
uf.init(n);
dij.init(n);
dij.dist[S]=0;
rep(i,1,x)
{
u=read(), v=read(), w=read();
G1.adde(u,v,w), G1.adde(v,u,w);
uf.merge(u,v);
}
rep(i,1,n)lis[uf.find(i)].emb(i);
rep(i,1,y)
{
u=read(), v=read(), w=read();
G2.adde(u,v,w);
indeg[uf.find(v)]++;
}
queue<ll> q;
rep(i,1,n)if(uf.find(i)==i and indeg[i]==0)q.em(i);
while(!q.empty())
{
auto x = q.front(); q.pop();
dij.run(G1,lis[x]);
for(auto u:lis[x])
{
forp(u,G2)
{
auto v=G2.to[p];
dij.dist[v] = min(dij.dist[v],dij.dist[u]+G2.w[p]);
indeg[uf.find(v)]--;
if(indeg[uf.find(v)]==0)q.em(uf.find(v));
}
}
}
rep(i,1,n)
{
if(dij.dist[i]>1e9)printf("NO PATH\n");
else printf("%lld\n",dij.dist[i]);
}
return 0;
}