2015 Syrian Private Universities Collegiate Programming Contest

  题目链接:https://vjudge.net/contest/152219#overview

  水题较多。就贴一下当时没做出来的几题好了。

  D,方法很简单,当时没想出来。用pos[x]表示x这个数已经是递增序列的第几个了,那么每次输入一个数x,令pos[x] = pos[x-1] + 1并更新答案ans即可。(当然所有pos都要预先设为0)

  H,记忆化搜索连样例都过不了= =,不知道为什么,觉得可能是因为一个点可以经过好几次的原因。参考了BH学长的方法,先floyd预处理出两两之间的距离,再暴力枚举需要访问点的顺序,维护最小值即可。代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8 typedef long long ll;
 9 const int N = 100 + 5;
10 typedef pair<int,int> pii;
11 const int inf = 0x3f3f3f3f;
12 
13 int dis[N][N];
14 int n,m,f;
15 int have[15];
16 int id[15];
17 void floyd()
18 {
19     for(int k=1;k<=n;k++)
20     {
21         for(int i=1;i<=n;i++)
22         {
23             for(int j=1;j<=n;j++)
24             {
25                 dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
26             }
27         }
28     }
29 }
30 
31 int main()
32 {
33     int T; cin >> T;
34     int kase = 1;
35     while(T--)
36     {
37         scanf("%d%d%d",&n,&m,&f);
38         memset(dis,inf,sizeof dis);
39         for(int i=1;i<=n;i++) dis[i][i] = 0;
40         for(int i=1;i<=m;i++)
41         {
42             int u,v,w;
43             scanf("%d%d%d",&u,&v,&w);
44             dis[u][v] = dis[v][u] = w;
45         }
46         for(int i=1;i<=f;i++) scanf("%d",have+i), id[i] = i;
47         floyd();
48         int ans = inf;
49         do
50         {
51             int sum = dis[1][have[id[1]]] + dis[have[id[f]]][n];
52             for(int i=1;i<f;i++) sum += dis[have[id[i]]][have[id[i+1]]];
53             ans = min(ans, sum);
54         }while(next_permutation(id+1,id+1+f));
55         printf("Case %d: %d
",kase++,ans);
56     }
57 }
H

  

  最后一题待补。

原文地址:https://www.cnblogs.com/zzyDS/p/6485871.html