vijos 天空

背景 Background
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。

描述 Description
给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起。
现在小杉要把所有云朵连成K个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。

输入格式 Input Format
每组测试数据的
第一行有三个数N,M,K(1<=N<=1000,1<=M<=10000,1<=K<=10)
接下来M个数每行三个数X,Y,L,表示X云和Y云可以通过L的代价连在一起。(1<=X,Y<=N,0<=L<10000)
30%的数据N<=100,M<=1000

输出格式 Output Format
对每组数据输出一行,仅有一个整数,表示最小的代价。
如果怎么连都连不出K个棉花糖,请输出‘No Answer‘。

样例输入 Sample Input
3 1 2
1 2 1

样例输出 Sample Output
1

时间限制 Time Limitatio
每个测试点1s
  
注释 Hint  
样例2:
Input:
3 1 1
1 2 1

Output:
No Answer

分析:
这个题其实很简单,就是尽量生成最小生成树(用克鲁斯卡尔算法,PS:传说中的kruskal,先排序,后贪心的算法),有可能图不是连通的,也就是,给的数据是好几个图,这样,我们将要求的最小生成树的个数设为k,我们生成的最小生成树的个数是m,若m=k,则直接输出代价就可以了,如果m>k则说明图的个数比要求的最小生成树个数小,怎么也无法构成k个最小生成树,也就是输出"No Answer"
如果m<k说明,求出的最小生成树个数比要求的最小生成树少,这里,我们可以用剪断枝的方法来将一棵树砍成两棵(PS:刚才是剪,现在怎么砍了?),此时,用贪心将用过的边最长的砍掉,然后,判断砍断后的树的数量是否与要求的数量相同,如果不相同就再砍掉当前的最长边,直到现在树的数目与所求数目相同时就输出,当然,还存在着如果把所有的用到的枝都砍掉还是不能凑够k时再输出"No Answer"

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<cstdlib>

#include<string>

using namespace std;

int n,m,k,set[110],cost[110],used[110];

bool flag;

struct line

{

int x,y,c;

}list[110];

bool cmp(line l,line t)

{

return l.c<t.c;

}

int find(int x)

{

if(set[x]!=x) set[x]=find(set[x]);

return set[x];

}

int main()

{

scanf("%d%d%d",&n,&m,&k);

for(int i=1;i<=m;i++)

scanf("%d%d%d",&list[i].x,&list[i].y,&list[i].c);

sort(list+1,list+1+m,cmp);

for(int i=1;i<=n;i++)

set[i]=i,cost[i]=0;

for(int i=1;i<=m;i++)

{

int x,y;

x=find(list[i].x);

y=find(list[i].y);

if(x!=y)

{

set[x]=y;

used[i]=true;

cost[x]+=cost[y]+list[i].c;

}

}

int maxx=0;

for(int i=1;i<=n;i++)

if(set[i]==i)

maxx++;

if(maxx>k)

printf("NO ANSWER\n");

else

{

int sum=0;

for(int i=1;i<=m;i++)

sum+=cost[i];

if(maxx==k)

printf("%d\n",sum);

else

{

for(int i=m;i>=1;i--)

{

if(used[i])

{

sum=sum-list[i].c;

maxx++;

if(maxx==k)

{

flag=true;

break;

}

}

}

if(flag) printf("NO ANSWER\n");

else printf("%d\n",sum);

}

}

return 0;

}

时间: 2024-10-05 05:05:02

vijos 天空的相关文章

vijos P1234口袋的天空(Kruskal)(最小生成树)

P1234口袋的天空 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 描述 给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起. 现在小杉要把一些云朵连在一起,做成K个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小. 格式 输入格式 每组测试数据的 第一行有三个数N,M,K(1<=N<=1000,1<=M<=10000,1<=K<=10) 接下来M个数每行三个数

vijos 1234 口袋的天空

最小生成树kruscal算法 #include<iostream> #include<algorithm> #include<cstring> #define maxn 10005 using namespace std; struct stu { int x,y; int t; }; stu mapp[maxn]; int f[1005]; int n,m,k,sum,flag; bool cmp(stu x,stu y) { return x.t<y.t; }

Vijos:P1234口袋的天空

背景 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 描述 给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起. 现在小杉要把一些云朵连在一起,做成K个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小. 格式 输入格式 每组测试数据的第一行有三个数N,M,K(1<=N<=1000,1<=M<=10000,1<=K<=10)接下来M个数每行三个数X,Y,L,表示X云

Vijos P1066 弱弱的战壕【多解,线段树,暴力,树状数组】

弱弱的战壕 描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒[email protected][email protected]). 但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT).这样,永恒就可以从别的地方进攻摧毁战壕,从而消灭mx的部队. 战壕都有一个保护范围,同它的攻击

建一座安全的“天空城” ——揭秘腾讯WeTest如何与祖龙共同挖掘手游安全漏洞

作者:腾讯WeTest手游安全测试团队商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. WeTest导读 <九州天空城3D>上线至今,长期稳定在APP Store畅销排行的前五,本文将介绍腾讯WeTest手游安全团队在游戏上线前为<九州天空城3D>挖掘安全漏洞的全过程. <九州天空城3D>(下文简称<九州>)是祖龙娱乐的一款正版授权次世代3D飞行手游,在8月,正式向全平台开放.作为一个前身是端游研发工作室的研发商,祖龙娱乐在<九州>

Vijos P1785 同学排序【模拟】

同学排序 描述 现有m位同学,第1位同学为1号,第2位同学为2号,依次第m位同学为m号.要求双号的学生站出来,然后余下的重新组合,组合完后,再次让双号的学生站出来,重复n次,问这时有多少同学出来站着? 样例1 样例输入1 1989 5 样例输出1 1926 限制 1s 提示 [数据范围] 1≤n≤10 100≤m≤100000 题目链接:https://vijos.org/p/1785 分析:站出序号为偶数的人,如果总人数为奇数,剩余人数向上取整再折半就好了! 下面给出AC代码: 1 #incl

Vijos 1057 盖房子

二次联通门 : Vijos 1057 盖房子 /* Vijos 1057 盖房子 简单的dp 当前点(i, j)所能构成的最大的正方形的边长 为点(i - 1, j - 1)与(i, j - 1), (i - 1, j)三点中最小的边长构成.. 一遍递推, 一边取最大即可 */ #include <cstdio> #define Max 1009 inline int min (int a, int b) { return a < b ? a : b; } inline int max

Vijos 1193 扫雷 【动态规划】

扫雷 描述 相信大家都玩过扫雷的游戏.那是在一个n*n的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,"余"任过流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和他8连通的格子里面雷的数目.现在棋盘是n*2的,第一列里某些格子是雷,而第二列没有雷,如:o 1* 2* 3* 2o 2* 2* 2 ('*'代表有雷,'o'代表无雷)由于第一类的雷有可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息求第一列雷有多少中摆放方案.

Vijos 1523 贪吃的九头龙 【树形DP】

贪吃的九头龙 背景 安徽省芜湖市第二十七中学测试题 NOI 2002 贪吃的九头龙(dragon) Description:OfficialData:OfficialProgram:Converted by JackDavid127 描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落. 有一天,有M个脑袋的九头龙看到一棵长有N个果子的果树,喜出望外,