题目:
n-1个人从1号点出发,到剩余n-1个宣传点,然后再回到1号点汇报结果,求所有人往返路径和的最小值
Input
输入由T个案例组成。输入的第一行只包含正整数T。
接下来是N和M,1 <= N,M <= 1000000,表示N个点和连接N个点的M条边。
然后有M行,每行包括三个值U,V,W,表示从点U到点V需要W的路程。你可以假设该图连通。
注意是单向通道!!!
Output
对于每个案例,打印一行,表示路径总和的最小值。
Sample Input
2
2 2
1 2 13
2 1 33
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50
Sample Output
46
210
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int inf=999999;
const int maxn=1111111;
int u[maxn],v[maxn],w[maxn];
int first[maxn],next[maxn];
int dis[maxn],book[maxn];
int que[maxn];
int p,q;
void deal()
{
int tail=1,head=1;
que[tail]=1;
tail++;
int i,j,k;
memset(book,0,sizeof(book));
memset(dis,inf,sizeof(dis));
dis[1]=0;
book[1]=1;
while(head<tail)
{
k=first[que[head]];
while(k!=-1)
{
if(dis[v[k]]>dis[u[k]]+w[k])
{
dis[v[k]]=dis[u[k]]+w[k];
if(book[v[k]]==0)
{
que[tail]=v[k];
tail++;
book[v[k]]=1;
}
}
k=next[k];
}
head++;
}
return ;
}
int main()
{
int t,i;
long long sum;
scanf("%d",&t);
while(t--)
{
sum=0;
memset(first,-1,sizeof(first));
scanf("%d %d",&p,&q);
for(i=1;i<=q;i++)
{
scanf("%d %d %d",&u[i],&v[i],&w[i]);
next[i]=first[u[i]];
first[u[i]]=i;
}
deal();
for(i=2;i<=p;i++)
sum+=dis[i];
int temp;
memset(first,-1,sizeof(first));
for(i=1;i<=q;i++)
{
temp=u[i];
u[i]=v[i];
v[i]=temp;
next[i]=first[u[i]];
first[u[i]]=i;
}
deal();
for(i=2;i<=p;i++)
sum+=dis[i];
printf("%lld\n",sum);
}
return 0;
}