将求的值算一下,会发现其实是求从1到每个点的最短路乘以点的权值的和,转化成简单的最短路,但是有几个很烦的地方,就是不能用vector,后来手写邻接表每次都遍历一遍结果也是T,后来存了每个链表的最后一个节点就过了。
代码:
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
long long w[100000];
long long dis[70000];
long long inf=1000000000000000000ll;
long long mmax;
int q[1000000];
struct con{
int u;
long long w;
con *next;
};
con *last[70000];
con* edu[70000];
int spfa(long long n){
int flag[70000],u;
for(int i=1;i<=n;i++){
dis[i]=inf;
flag[i]=0;
}
dis[1]=0;
flag[1]=1;
int h=0,r=0;
q[r++]=1;
while(h!=r){
int cnt=q[h];
h++;
con *tmp=edu[cnt]->next;
for(;tmp!=NULL;tmp=tmp->next){
int tu=tmp->u,tw=tmp->w;
if(dis[cnt]+tw<dis[tu]){
dis[tu]=dis[cnt]+tw;
if(!flag[tu]){
q[r++]=tu;
flag[tu]=1;
}
}
}
flag[cnt]=0;
}
mmax=0;
for(int i=1;i<=n;i++){
if(dis[i]==inf)
return 0;
mmax+=dis[i]*w[i];
}
return 1;
}
main(){
int t;
scanf("%d",&t);
while(t--){
int v,e;
scanf("%d%d",&v,&e);
for(int i=1;i<=v;i++){
scanf("%lld",&w[i]);
edu[i]=new con;
edu[i]->next=NULL;
last[i]=edu[i];
}
for(int i=1;i<=e;i++){
int a,b;
long long c;
scanf("%d%d%lld",&a,&b,&c);
con *tmp=last[a];
con *aa=new con;
tmp->next=aa;
aa->u=b;
aa->w=c;
aa->next=NULL;
last[a]=aa;
tmp=last[b];
con *bb=new con;
tmp->next=bb;
bb->u=a;
bb->w=c;
bb->next=NULL;
last[b]=bb;
}
if(v==0 || v==1){
printf("0\n");
}
else{
if(!spfa(v)){
printf("No Answer\n");
}
else
printf("%lld\n",mmax);
}
}
}