csuoj 1116: Kingdoms

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1116

1116: Kingdoms

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 293  Solved: 82
[Submit][Status][Web Board]

Description

A kingdom has n cities numbered 1 to n, and some bidirectional roads connecting cities. The capital is always city 1.

After a war, all the roads of the kingdom are destroyed. The king wants to rebuild some of the roads to connect the cities, but unfortunately, the kingdom is running out of money. The total cost of rebuilding roads should not exceed K.

Given the list of m roads that can be rebuilt (other roads are severely damaged and cannot be rebuilt), the king decided to maximize the total population in the capital and all other cities that are connected (directly or indirectly) with the capital (we call it "accessible population"), can you help him?

Input

The first line of input contains a single integer T (T<=20), the number of test cases.

Each test case begins with three integers n(4<=n<=16), m(1<=m<=100) and K(1<=K<=100,000).

The second line contains n positive integers pi (1<=pi<=10,000), the population of each city.

Each of the following m lines contains three positive integers u, v, c (1<=u,v<=n, 1<=c<=1000), representing a destroyed road connecting city u and v, whose rebuilding cost is c.

Note that two cities can be directly connected by more than one road, but a road cannot directly connect a city and itself.

Output

For each test case, print the maximal accessible population.

Sample Input

2
4 6 6
500 400 300 200
1 2 4
1 3 3
1 4 2
4 3 5
2 4 6
3 2 7
4 6 5
500 400 300 200
1 2 4
1 3 3
1 4 2
4 3 5
2 4 6
3 2 7

Sample Output

1100
1000

HINT

Source

湖南省第八届大学生计算机程序设计竞赛

分析;

此题可以先确定1是在点集里,然后暴力枚举其它城市是否要连,对每个枚举的结果求最小生成树,选出符合条件的最优解。

AC代码:

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 const int maxn=0x3f3f3f3f;
  6 int n,m,k;
  7 int population[20];
  8 int Map[20][20];
  9 bool exits[20];
 10 bool vis[20];
 11 int d[20];
 12 int p;
 13 void init(int n)
 14 {
 15     for(int i=1; i<=n; i++)
 16     {
 17         for(int j=1; j<=n; j++)
 18         {
 19             Map[i][j]=(i!=j?maxn:0);
 20         }
 21     }
 22 }
 23 int prim()
 24 {
 25     int sum=0;
 26     memset(vis,false,sizeof(vis));
 27     for(int i=1; i<=n; i++)
 28     {
 29         d[i]=Map[1][i];
 30     }
 31     vis[1]=true;
 32     for(int i=2; i<=n; i++)
 33     {
 34
 35         int min=maxn,mini;
 36         for(int j=1; j<=n; j++)
 37         {
 38             if(!vis[j]&&exits[j]&&d[j]<min)
 39             {
 40                 min=d[j];
 41                 mini=j;
 42             }
 43         }
 44         if(min==maxn) break;
 45         sum+=min;
 46         vis[mini]=true;
 47         for(int k=1; k<=n; k++)
 48         {
 49             if(exits[k]&&!vis[k]&&Map[mini][k]<d[k])
 50             {
 51                 d[k]=Map[mini][k];
 52             }
 53         }
 54
 55
 56     }
 57     int cnt1=0,cnt2=0;
 58     for(int i=1;i<=n;i++){
 59         cnt1+=exits[i];
 60     }
 61     for(int i=1;i<=n;i++){
 62         cnt2+=vis[i];
 63     }
 64     if(cnt1==cnt2)
 65     return sum;
 66     else return maxn;
 67
 68 }
 69
 70 void dfs(int cur)
 71 {
 72     if(cur>n)
 73     {
 74         int pr=prim();
 75         int temp=0;
 76         if(pr<=k)
 77         {
 78             for(int i=1; i<=n; i++)
 79             {
 80                 if(exits[i])
 81                 {
 82                     temp+=population[i];
 83                 }
 84             }
 85             if(temp>p) p=temp;
 86         }
 87         return ;
 88     }
 89     for(int i=0; i<2; i++)
 90     {
 91         exits[cur]=i==1?true:false;
 92         dfs(cur+1);
 93     }
 94 }
 95 int main()
 96 {
 97     int t;
 98     scanf("%d",&t);
 99     while(t--)
100     {
101         scanf("%d%d%d",&n,&m,&k);
102         for(int i=1; i<=n; i++)
103         {
104             scanf("%d",&population[i]);
105         }
106         init(n);
107         for(int i=0; i<m; i++)
108         {
109             int from,to,c;
110             scanf("%d%d%d",&from,&to,&c);
111             if(Map[from][to]>c)
112             {
113                 Map[from][to]=Map[to][from]=c;
114             }
115         }
116         p=population[1];
117         exits[1]=true;
118         dfs(2);
119         printf("%d\n",p);
120     }
121     return 0;
122 }

时间: 2024-08-04 23:37:51

csuoj 1116: Kingdoms的相关文章

CSU 1116 Kingdoms(枚举最小生成树)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1116 解题报告:一个国家有n个城市,有m条路可以修,修每条路要一定的金币,现在这个国家只有K个金币,每个城市有一些人,要你求怎么修路使得总的费用在K的范围内,同时使得跟首都连接的城市的人口(包括首都的人口)要最多,问最多的人口是多少. 枚举连接哪些城市,然后分别构造最小生成树. 1 #include<cstdio> 2 #include<cstring> 3 #inclu

CSU 1116 Kingdoms 最小生成树(prim)

由于点数只有16,而点1又必选,暴力枚举选点情况,每次做一个最小生成树 这里用的prim算法,要注意的是存在选取这些点但找不到生成树的情况,需要将之排出 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<map> using namespace std; const int INF=0x3f3f3f3f; const int max

CSU 1116 Kingdoms

传送门 Description A kingdom has n cities numbered 1 to n, and some bidirectional roads connecting cities. The capital is always city 1. After a war, all the roads of the kingdom are destroyed. The king wants to rebuild some of the roads to connect the

1116 删除元素

题目来源:https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1116Description输入一个递增有序的整型数组A有n个元素,删除下标为i的元素,使其仍保持连续有序.注意,有效下标从0开始. 定义如下两个函数分别实现删除元素操作和数组输出操作.void del(int a[], int n, int i);  /*删除数组a中下标为i的元素*/void PrintArr(int a[], int n); /*输出数组a的前n个元素*/ Inpu

hihoCoder - 1116 - 计算 (线段树)

计算 题目传送:#1116 : 计算 这里说下sum,pre,suf,ji数组的含义: sum:所求答案 pre:所有前缀积之和 suf:所有后缀积之和 ji:区间内所有数之积 以一个例子说明: 比如我们现在正在合并区间{3,4},{2,5} 而区间{3,4}所表示的 sum1=3 + 4 + 3 * 4 = 19 pre1 = 3 + 3 * 4 = 12 suf1 = 3 * 4 + 4 = 16 ji1 = 3 * 4 = 12 而区间{2,5} sum2 = 2 + 5 + 2 * 5

ACdreamOJ 1116 斐波那契数列+hash计算后缀

http://acdream.info/problem?pid=1116 Problem Description give you a string, please output the result of the following function mod 1000000007 n is the length of the string f() is the function of fibonacci, f(0) = 0, f(1) = 1... a[i] is the total numb

CSUOJ 1010 Water Drinking

Description The Happy Desert is full of sands. There is only a kind of animal called camel living on the Happy Desert. ‘Cause they live here, they need water here. Fortunately, they find a pond which is full of water in the east corner of the desert.

CSUOJ 1217 奇数个的那个数

Description 给定些数字,这些数中只有一个数出现了奇数次,找出这个数. Input 每组数据第一行n表示数字个数,1 <= n <= 2 ^ 18 且 n % 2 == 1. 接下来n行每行一个32位有符号整数. Output 出现奇数次那个数,每组数据对应一行. Sample Input 5 1 1 2 2 3 7 1 2 1 2 2 3 3 Sample Output 3 2 看了大神的代码 使用位运算o(╯□╰)o 1 # include <stdio.h> 2 i

Aizu 2164 CSUOJ 1436 Revenge of the Round Table

dp套一个burnside的壳子核心还是dpdp[i]表示有i个循环节时的染色方案数注意在dp的时候,不需要考虑重构的问题因为burnside会解决重构的问题dpA[i][j]表示以A开头,长度为i,结尾为j个A的合法方案数dpB[i][j]表示以B开头,长度为i,结尾为j个A的合法方案数接下来我们用dpA,dpB来计算dp[i]显然对于所有的dpB[i][1~k]都是满足dp[i]的因为它表示以B开头,以A结尾的染色方案,且结尾没有超过k个另外还有一部分就是以A开头的了假设我们在整个串的最前面