Shopping(hdu 3768)
题意:给你一个无向图,求从0号点开始遍历所有的指定点再回到0号点的最短路径
#include<cstdio> #include<iostream> #include<queue> #include<algorithm> #include<cstring> #define N 100010 #define ll long long #define INF 10000000000000LL using namespace std; ll head[N],vis[N],dis[N],f[15][15],a[15],b[15],n,m,k,ans=INF; struct node { ll v,pre,t; };node e[N*2]; ll read() { ll num=0,flag=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*flag; } void add(ll i,ll x,ll y,ll z) { e[i].v=y; e[i].t=z; e[i].pre=head[x]; head[x]=i; } ll spfa(ll s,ll t) { for(ll i=1;i<=n;i++)dis[i]=INF; memset(vis,0,sizeof(vis)); queue<int> q; q.push(s);vis[s]=1;dis[s]=0; while(!q.empty()) { ll u=q.front();vis[u]=0;q.pop(); for(ll i=head[u];i;i=e[i].pre) if(dis[e[i].v]>dis[u]+e[i].t) { dis[e[i].v]=dis[u]+e[i].t; if(!vis[e[i].v]) { vis[e[i].v]=1; q.push(e[i].v); } } } return dis[t]; } void work() { n=read();m=read(); for(ll i=1;i<=m;i++) { ll x=read()+1,y=read()+1,z=read(); add(i*2-1,x,y,z);add(i*2,y,x,z); } k=read();a[1]=1; for(ll i=2;i<=k+1;i++) a[i]=read()+1; for(ll i=1;i<=k+1;i++) for(ll j=i+1;j<=k+1;j++) f[i][j]=f[j][i]=spfa(a[i],a[j]); for(ll i=1;i<=k+1;i++)b[i]=i; do { ll p=f[b[1]][b[k+1]]; for(ll i=2;i<=k+1;i++) p+=f[b[i-1]][b[i]]; ans=min(ans,p); }while(next_permutation(b+2,b+k+2)); cout<<ans<<endl; } int main() { freopen("jh.in","r",stdin); ll T=read(); while(T--) { memset(head,0,sizeof(head)); memset(f,0,sizeof(f)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(e,0,sizeof(e)); ans=INF; work(); } return 0; }