最短路 + 最小生成树
代码量小,一会就写过了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define N 1000005
using namespace std;
struct node{
long long u,v,w;
}e[N],r[N];
long long n,m,first[N],nxt[N],fa[N],tot,cnt=1,ans_,white,vis[N],dis[N],check[N],co[N],flag;
void add(long long u,long long v,long long w){
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
nxt[cnt]=first[u];
first[u]=cnt;
}
void spfa(){
queue<long long>q;
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[0]=0;
vis[0]=1;
q.push(0);
while(!q.empty()){
long long u=q.front();
q.pop();
vis[u]=0;
for(long long i=first[u];i;i=nxt[i]){
long long v=e[i].v;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
for(int i=1;i<=n;i++)if(dis[i]==4557430888798830399){
flag=1;
return;
}
q.push(0);
memset(vis,0,sizeof(vis));
vis[0]=1;
while(!q.empty()){
long long u=q.front();
q.pop();
vis[u]=0;
for(long long i=first[u];i;i=nxt[i]){
if(check[i])continue;
long long v=e[i].v;
if(dis[v]==dis[u]+e[i].w){
check[i]=1;
//cout<<" "<<i<<" "<<e[i].u<<" "<<e[i].v<<endl;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
}
long long find(long long x){
if(x!=fa[x])return fa[x]=find(fa[x]);
return fa[x];
}
void merge(long long x,long long y){
long long f1=find(x),f2=find(y);
if(f1!=f2){
fa[f1]=f2;
}
}
void kruskal(){
long long cnt_=0;
for(long long i=1;i<=tot;i++){
long long u=r[i].u;
long long v=r[i].v;
if(find(u)!=find(v)){
merge(u,v);
ans_+=r[i].w;
cnt_++;
if(cnt_==white)return;
}
}
}
bool cmp(node a,node b){
return a.w<b.w;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(long long i=1;i<=n;i++){
fa[i]=i;
cin>>co[i];
if(co[i])add(0,i,0),add(i,0,0);
else white++;
}
for(long long i=1;i<=m;i++){
long long a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
spfa();//记录最短路边集
if(flag){
cout<<"impossible";
return 0;
}
for(long long i=2;i<=cnt;i++){
if(check[i]||check[i^1]){
if(e[i].w==0)continue;
//cout<<e[i].u<<" "<<e[i].v<<endl;
r[++tot].u=e[i].u;
r[tot].v=e[i].v;
r[tot].w=e[i].w;
}
}
sort(r+1,r+tot+1,cmp);
kruskal();
cout<<ans_;
return 0;
}