第一题

  其实是个TSP问题(然而我没发现),但是关键点很少,只有5个,所以用dij+heap分别预处理出来这五个点为源的最短路……

  然后枚举起点 i ,枚举这5个点的经过顺序,然后O(1)处理答案就可以了……

  容易写错的地方是 五个点的标号(a[i]),以及第几个点(i),这个地方容易搞混……

  我爆零的地方是:有个地方原来写的是 i 循环,然而我修改了以后内层变成 j 循环了,但是我没改循环内的语句……

  还有就是数组应该开 len[M<<1]的,我开成len[N<<1] 了。

 1 #include<queue>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 using namespace std;
12 
13 int getint(){
14     int v=0,sign=1; char ch=getchar();
15     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
16     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
17     return v*sign;
18 }
19 typedef long long LL;
20 const int N=10010,M=50010,INF=~0u>>2;
21 /*******************template********************/
22 int to[M<<1],next[M<<1],len[M<<1],head[N],cnt;
23 void add(int x,int y,int z){
24     to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=z;
25     to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt; len[cnt]=z;
26 }
27 
28 int n,m,k;
29 int a[10],b[10],d[10][N];
30 bool vis[N],sign[N];
31 struct node{int x,d;};
32 bool operator < (node a,node b){return a.d>b.d;}
33 priority_queue<node>Q;
34 
35 void dij(int s){
36     memset(d[s],0x3f,sizeof d[s]);
37     memset(vis,0,sizeof vis);
38     d[s][a[s]]=0;
39     Q.push((node){a[s],0});
40     while(!Q.empty()){
41         int x=Q.top().x; Q.pop();
42         if (vis[x]) continue;
43         vis[x]=1;
44         for(int i=head[x];i;i=next[i])
45             if (d[s][to[i]]>d[s][x]+len[i]){
46                 d[s][to[i]]=d[s][x]+len[i];
47                 Q.push((node){to[i],d[s][to[i]]});
48             }
49     }
50 }
51 int ans=1e9+10;
52 void check(){
53     int tmp=0;
54     F(i,1,n){
55         tmp=0;
56         if (!sign[i]){
57             tmp+=d[b[1]][i]+d[b[k]][i];
58             F(j,1,k-1) tmp+=d[b[j]][ a[b[j+1]] ];
59             ans=min(ans,tmp);
60         }
61     }
62 }
63 bool chk[10];
64 void dfs(int x){
65     if (x==k+1) check();
66     F(i,1,k) if (!chk[i]){
67         b[x]=i;
68         chk[i]=1;
69         dfs(x+1);
70         b[x]=0;
71         chk[i]=0;
72     }
73 }
74 int main(){
75     n=getint(); m=getint(); k=getint();
76     F(i,1,k){
77         a[i]=getint();
78         sign[a[i]]=1;
79     }
80     F(i,1,m){
81         int x=getint(),y=getint(),z=getint();
82         add(x,y,z);
83     }
84     F(i,1,k) dij(i);
85     dfs(1);
86     printf("%d\n",ans);
87     return 0;
88 }
View Code

相关文章: