CSP第十五次题目(前四题)附有c++和java代码
CSP15目录
1.小明上学
试题编号: 1
试题名称: 小明上学
时间限制: 1.0s
内存限制: 512.0MB
问题描述: 题目背景
小明是汉东省政法大学附属中学的一名学生,他每天都要骑自行车往返于家和学校。为了能尽可能充足地睡眠,他希望能够预计自己上学所需要的时间。他上学需要经过数段道路,相邻两段道路之间设有至多一盏红绿灯。
京州市的红绿灯是这样工作的:每盏红绿灯有红、黄、绿三盏灯和一个能够显示倒计时的显示牌。假设红绿灯被设定为红灯 r 秒,黄灯 y 秒,绿灯 g 秒,那么从 0 时刻起,[0,r) 秒内亮红灯,车辆不许通过;[r, r+g) 秒内亮绿灯,车辆允许通过;[r+g, r+g+y) 秒内亮黄灯,车辆不许通过,然后依次循环。倒计时的显示牌上显示的数字 l(l > 0)是指距离下一次信号灯变化的秒数。
问题描述
一次上学的路上,小明记录下了经过每段路的时间,和各个红绿灯在小明到达路口时的颜色和倒计时秒数。希望你帮忙计算此次小明上学所用的时间。
输入格式
输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 106。
输入的第二行包含一个正整数 n(n ≤ 100),表示小明总共经过的道路段数和看到的红绿灯数目。
接下来的 n 行,每行包含空格分隔的两个整数 k、t。k=0 表示经过了一段道路,耗时 t 秒,此处 t 不超过 106;k=1、2、3 时,分别表示看到了一个红灯、黄灯、绿灯,且倒计时显示牌上显示的数字是 t,此处 t 分别不会超过 r、y、g。
输出格式
输出一个数字,表示此次小明上学所用的时间。
样例输入
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
样例输出
70
样例说明
小明先经过第一段道路,用时 10 秒,然后等待 5 秒的红灯,再经过第二段道路,用时 11 秒,然后等待 2 秒的黄灯和 30 秒的红灯,再经过第三段、第四段道路,分别用时6、3秒,然后通过绿灯,再经过最后一段道路,用时 3 秒。共计 10 + 5 + 11 + 2 + 30 + 6 + 3 + 3=70 秒。
评测用例规模与约定
测试点 1, 2 中不存在任何信号灯。
测试点 3, 4 中所有的信号灯在被观察时均为绿灯。
测试点 5, 6 中所有的信号灯在被观察时均为红灯。
测试点 7, 8 中所有的信号灯在被观察时均为黄灯。
测试点 9, 10 中将出现各种可能的情况。
c++代码(100分)
#include<iostream>
using namespace std;
int main()
{
int i,red,yellow,green,n,a,b,sum=0;
cin>>red>>yellow>>green;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a>>b;
if(a==0)
sum=sum+b;
else if(a==1)
sum=sum+b;
else if(a==2)
sum=sum+red+b;
}
cout<<sum;
return 0;
}
java代码(100分)
package csp15;
import java.util.*;
public class Main {
public static void main(String[] args){
int i,red,yellow,green,n,a,b,sum=0;
Scanner input=new Scanner(System.in);
red = input.nextInt();
yellow = input.nextInt();
green = input.nextInt();
n=input.nextInt();
for(i=1;i<=n;i++)
{
a=input.nextInt();
b=input.nextInt();
if(a==0)
sum=sum+b;
else if(a==1)
sum=sum+b;
else if(a==2)
sum=sum+red+b;
}
System.out.println(sum);
input.close();
}
}
2.小明放学
试题编号: 2
试题名称: 小明放学
时间限制: 1.0s
内存限制: 512.0MB
问题描述: 题目背景
汉东省政法大学附属中学所在的光明区最近实施了名为“智慧光明”的智慧城市项目。具体到交通领域,通过“智慧光明”终端,可以看到光明区所有红绿灯此时此刻的状态。小明的学校也安装了“智慧光明”终端,小明想利用这个终端给出的信息,估算自己放学回到家的时间。
问题描述
一次放学的时候,小明已经规划好了自己回家的路线,并且能够预测经过各个路段的时间。同时,小明通过学校里安装的“智慧光明”终端,看到了出发时刻路上经过的所有红绿灯的指示状态。请帮忙计算小明此次回家所需要的时间。
输入格式
输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 106。
输入的第二行包含一个正整数 n,表示小明总共经过的道路段数和路过的红绿灯数目。
接下来的 n 行,每行包含空格分隔的两个整数 k、t。k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 106;k=1、2、3 时,分别表示出发时刻,此处的红绿灯状态是红灯、黄灯、绿灯,且倒计时显示牌上显示的数字是 t,此处 t 分别不会超过 r、y、g。
输出格式
输出一个数字,表示此次小明放学回家所用的时间。
样例输入
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
样例输出
46
样例说明
小明先经过第一段路,用时 10 秒。第一盏红绿灯出发时是红灯,还剩 5 秒;小明到达路口时,这个红绿灯已经变为绿灯,不用等待直接通过。接下来经过第二段路,用时 11 秒。第二盏红绿灯出发时是黄灯,还剩两秒;小明到达路口时,这个红绿灯已经变为红灯,还剩 11 秒。接下来经过第三、第四段路,用时 9 秒。第三盏红绿灯出发时是绿灯,还剩 10 秒;小明到达路口时,这个红绿灯已经变为红灯,还剩两秒。接下来经过最后一段路,用时 3 秒。共计 10+11+11+9+2+3 = 46 秒。
评测用例规模与约定
有些测试点具有特殊的性质:
* 前 2 个测试点中不存在任何信号灯。
测试点的输入数据规模:
* 前 6 个测试点保证 n ≤ 103。
* 所有测试点保证 n ≤ 105。
c++代码(100分)
#include<iostream>
using namespace std;
int main()
{
long long int i,red,yellow,green,color,n,a,b,sum=0;
cin>>red>>yellow>>green;
color=red+yellow+green;
cin>>n;
for(i=1;i<=n;i++)//红->绿->黄->红
{
cin>>a>>b;
if(a==0)
sum=sum+b;
else if(a==1)//红灯
if(sum-b>0)
{
if((sum-b)%color>=green&&(sum-b)%color<(green+yellow))//处于黄灯
sum=sum+red+(yellow-((sum-b)%color-green));
if((sum-b)%color>=(green+yellow)&&(sum-b)%color<color)//处于红灯
sum=sum+(red-((sum-b)%color-green-yellow));
}
else sum=sum+b-sum;
else if(a==2)//黄灯
if(sum-b>0)
{
if((sum-b)%color>=0&&(sum-b)%color<red)//处于红灯
sum=sum+(red-(sum-b)%color);
if((sum-b)%color>=(red+green)&&(sum-b)%color<color)//处于黄灯
sum=sum+red+(yellow-((sum-b)%color-green-red));
}
else sum=sum+b-sum+red;
else if(a==3)//绿灯
if(sum-b>0)
{
if((sum-b)%color>=0&&(sum-b)%color<yellow)//处于黄灯
sum=sum+red+(yellow-(sum-b)%color);
if((sum-b)%color>=yellow&&(sum-b)%color<(yellow+red))//处于红灯
sum=sum+(red-((sum-b)%color-yellow));
}
else sum=sum;
//cout<<sum<<endl;
}
cout<<sum;
return 0;
}
java代码(100分)
package csp15;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
long i,red,yellow,green,color,n,a,b,sum=0;
Scanner input=new Scanner(System.in);
red=input.nextInt();
yellow=input.nextInt();
green=input.nextInt();
color=red+yellow+green;
n=input.nextInt();
for(i=1;i<=n;i++)//红->绿->黄->红
{
a=input.nextInt();
b=input.nextInt();
if(a==0)
sum=sum+b;
else if(a==1)//红灯
if(sum-b>0)
{
if((sum-b)%color>=green&&(sum-b)%color<(green+yellow))//处于黄灯
sum=sum+red+(yellow-((sum-b)%color-green));
if((sum-b)%color>=(green+yellow)&&(sum-b)%color<color)//处于红灯
sum=sum+(red-((sum-b)%color-green-yellow));
}
else sum=sum+b-sum;
else if(a==2)//黄灯
if(sum-b>0)
{
if((sum-b)%color>=0&&(sum-b)%color<red)//处于红灯
sum=sum+(red-(sum-b)%color);
if((sum-b)%color>=(red+green)&&(sum-b)%color<color)//处于黄灯
sum=sum+red+(yellow-((sum-b)%color-green-red));
}
else sum=sum+b-sum+red;
else if(a==3)//绿灯
if(sum-b>0)
{
if((sum-b)%color>=0&&(sum-b)%color<yellow)//处于黄灯
sum=sum+red+(yellow-(sum-b)%color);
if((sum-b)%color>=yellow&&(sum-b)%color<(yellow+red))//处于红灯
sum=sum+(red-((sum-b)%color-yellow));
}
//else sum=sum;
//cout<<sum<<endl;
}
System.out.println(sum);
input.close();
}
}
3.CIDR合并(100分)
试题编号: 3
试题名称: CIDR合并
时间限制: 1.0s
内存限制: 512.0MB
样例输入
2
1
2
样例输出
1.0.0.0/8
2.0.0.0/8
样例输入
2
10/9
10.128/9
样例输出
10.0.0.0/8
样例输入
2
0/1
128/1
样例输出
0.0.0.0/0
c++代码(100分)
#include<iostream>
#include<list>
#include<string>
using namespace std;
struct IP{
string ip;//ip地址
int len;//前缀长度
IP(){}
//以IP地址为第一关键字,前缀长度为第二关键字,从小到大排序
IP(string ip,int len):ip(ip),len(len){}
bool operator <(const IP &a)const
{
return ip==a.ip?(len<a.len):(ip<a.ip);
}
};
list<IP>ipAddress;
//将整数n(0<=n<256)化成二进制数
string itos(int n)
{
string res="00000000";
int k=7;
while(n)
{
res[k--]=n%2+'0';
n/=2;
}
return res;
}
//读取ip前缀
void read()
{
string ip="";
char ch;
int len=0,k=0,val=0;//k记录小数点的数量
bool flag=false;
while((ch=getchar())!='\n')//读入'\n'退出
{
if(ch=='.')//读入小数点
{
k++;
ip+=itos(val);
val=0;
}
else if(ch=='/')
{
ip+=itos(val);
val=0;
flag=true;
}
else
val=val*10+ch-'0';
}
len=(flag?val:(k+1)*8);//如果flag=true len就等于val,否则就是省略长度型
if(!flag) ip+=itos(val);//flag=false,表示是省略后缀型,那么val就是ip前缀的一部分
while(k<3)//补零
{
ip+=itos(0);
k++;
}
ipAddress.insert(ipAddress.end(),IP(ip,len));//将元素插入list中
}
int main()
{
int n,i;
scanf("%d",&n);
getchar();//读取空白符
for(i=1;i<=n;i++)//读入n个ip前缀
read();
ipAddress.sort();//第一步:排序
list<IP>::iterator cur;
list<IP>::iterator next;
for(cur=ipAddress.begin();cur!=ipAddress.end();)//第二步:从小到大合并 end()指向最后一个元素的下一个元素,.bengin()返回当前vector容器中起始元素的引用
{
next=cur;
next++;
if(next==ipAddress.end()) break;//如果cur已经是最后一个元素了就退出
for(i=0;i<cur->len;i++)
if(cur->ip[i]!=next->ip[i])
break;
if(i==cur->len)//如果next是cur的子集,就删除next
ipAddress.erase(next);//erase()删除next一行
else
cur++;//查看下一个元素
}
for(cur=ipAddress.begin();cur!=ipAddress.end();)//第三步:统计合并 10/9 10.128/9
{
next=cur;
next++;
if(next==ipAddress.end()) break;
if(cur->len==next->len&&cur->len>0&&cur->ip[cur->len-1]=='0')
{
for(i=0;i<cur->len-1;i++)
if(cur->ip[i]!=next->ip[i])
break;
if(i==cur->len-1)
{
ipAddress.erase(next);
cur->len-=1;
if(cur!=ipAddress.begin())//如果cur的前面还有元素,则让cur--
{
cur--;
continue;
}
}
}
cur++;//考虑下一个元素
}
//输出
for(cur=ipAddress.begin();cur!=ipAddress.end();cur++)
{
for(i=7;i<32;i+=8)
{
int temp=0;
for(int j=i-7;j<=i;j++)
temp=temp*2+cur->ip[j]-'0';//注意权值为2
printf("%d",temp);
if(i!=31) printf(".");
}
printf("/%d\n",cur->len);
}
return 0;
}
java代码(60分)
这个是根据上面100分的c++代码改的,可只有60分哈
package csp15;
import java.util.Scanner;
class IP {
String ip;//地址
int len;//前缀长度
IP(){}
//以IP地址为第一关键字,前缀长度为第二关键字,从小到大排序
}
public class Main {
public static String itos(int n){
char []str =new char[8];
for(int i=0;i<8;i++){
str[i]='0';
}
int k=7;
while(n!=0){
if(n%2==0){
str[k--]='0';
}
else
str[k--]='1';
n = n/2;
}
String Str=new String(str);
return Str;
}
public static IP read(String Str){
String ip = "";
char ch;
IP a=new IP();
int k=0,val=0;//k记录小数点的数量
boolean flag=false;
int n=Str.length();
for(int i=0;i<n;i++)//读入'\n'退出
{
ch=Str.charAt(i);
if(ch=='.')//读入小数点
{
k++;
ip+=itos(val);
val=0;
}
else if(ch=='/')
{
ip+=itos(val);
val=0;
flag=true;
}
else
val=val*10+ch-'0';
}
int len;
if(flag==true){
len=val;//如果flag=true len就等于val,否则就是省略长度型
}
else
len=(k+1)*8;
if(!flag) ip+=itos(val);//flag=false,表示是省略后缀型,那么val就是ip前缀的一部分
while(k<3)//补零
{
ip+=itos(0);
k++;
}
a.ip=ip;
a.len=len;
return a;
}
public static IP[] sort1(IP[] a,int n){
String temp;
int lens;
for(int i=0;i<n-1;i++)
for(int j=0;j<n-i-1;j++){
if(a[j].ip.compareTo(a[j+1].ip)==1){
temp=a[j].ip;
lens=a[j].len;
a[j].ip=a[j+1].ip;
a[j].len=a[j+1].len;
a[j+1].ip=temp;
a[j+1].len=lens;
}
else if(a[j].ip.compareTo(a[j+1].ip)==0){
if(a[j].len>a[j+1].len){
lens=a[j].len;
a[j].len=a[j+1].len;
a[j+1].len=lens;
}
}
}
return a;
}
public static void main(String[] args){
int n,i,k;
Scanner input=new Scanner(System.in);
n=input.nextInt();
IP[] IPaddress=new IP[10000];
IP[] IPaddress1=new IP[10000];
for(i=0;i<n;i++){
IPaddress[i]=read(input.next());
}
IPaddress1=sort1(IPaddress,n);
for(i=0;i<n;){//第二步:从小到大合并
int j=i;
j++;
if(j==n){
break;
}
for(k=0;k<IPaddress1[i].len;k++){
if(IPaddress1[i].ip.charAt(k)!=IPaddress1[j].ip.charAt(k))
break;
}
if(k==IPaddress1[i].len){
for(int x=j;x<n-1;x++){
IPaddress1[j].ip=IPaddress1[j+1].ip;
IPaddress1[j].len=IPaddress1[j+1].len;
}
n--;
}
else i++;
}
for(i=0;i<n;){//同级合并
int j = i;
j++;
if(j==n){
break;
}
if(IPaddress1[i].len==IPaddress1[j].len&&IPaddress1[i].len>0&&IPaddress1[i].ip.charAt(IPaddress1[i].len-1)=='0'){
for(k=0;k<(IPaddress1[i].len-1);k++){
if(IPaddress1[i].ip.charAt(k)!=IPaddress1[j].ip.charAt(k)){
break;
}
}
if(k==IPaddress1[i].len-1){
for(int x=j;x<n-1;x++){
IPaddress1[j].ip=IPaddress1[j+1].ip;
IPaddress1[j].len=IPaddress1[j+1].len;
}
n--;
IPaddress1[i].len-=1;
if(i!=0){
i--;
continue;
}
}
}
i++;
}
for(i=0;i<n;i++){
for(int j=7;j<32;j+=8){
int temp=0;
for(k=j-7;k<=j;k++){
if(IPaddress1[i].ip.charAt(k)=='1')
temp=temp*2+1;
else
temp=temp*2;
}
System.out.print(temp);
if(j!=31)
System.out.print(".");
}
System.out.println("/"+IPaddress1[i].len);
}
/*
for(i=0;i<n;i++){
System.out.println(IPaddress1[i].ip);
System.out.println(IPaddress1[i].len);
}
*/
input.close();
}
}
/*
2
10/9
10.128/9
*/
java代码(100分)
转载JAVA代码的博客(我写的没有满分,借鉴一下别人的)
https://blog.****.net/xuzonghao
import java.io.*;
import java.util.*;
import java.lang.*;
class prefix implements Comparable<prefix>{
public int[] ip;
public int len;
public prefix(int[] ip,int len) {
this.ip = ip;
this.len = len;
}
public int compareTo(prefix x) {
for(int i = 0; i < 4; i++) {
if(this.ip[i] != x.ip[i])
return this.ip[i] - x.ip[i];
}
return this.len - x.len;
}
}
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
/**
* call this method to initialize reader for InputStream
*/
static void init(InputStream input) {
reader = new BufferedReader(
new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
/**
* get next word
*/
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
//TODO add check for eof if necessary
tokenizer = new StringTokenizer(
reader.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}
public class Main {
public static void main(String[] args) throws IOException {
// Scanner in = new Scanner(System.in);
// int n = Integer.parseInt(in.nextLine());
Reader.init(System.in);
int n = Reader.nextInt();
List<prefix> list = new ArrayList<prefix>();
//读入并转换成prefix类
for(int d = 0;d<n;d++) {
// String ip = in.nextLine();
String ip = Reader.next();
//构建prefix对象
int[] Ip = new int[4];
int len = 0;
int index = ip.indexOf("/");
if(index != -1) {
String[] b = ip.split("/");
len = Integer.parseInt(b[1]);
String str = b[0];
if(str.indexOf(".") != -1) b = str.split("\\.");
else b = new String[] {str};
//同时处理了省略后缀型和标准型
for(int i = 0; i < b.length; i++) Ip[i] = Integer.parseInt(b[i]);
for(int i = b.length; i<4 ;i++) Ip[i] = 0;
}else {//省略长度型
String[] b = new String[]{ip};
if(ip.indexOf(".") != -1) b = ip.split("\\.");
len = b.length * 8;
for(int i = 0;i < b.length;i++) Ip[i] = Integer.parseInt(b[i]);
for(int i = b.length; i < 4; i++) Ip[i] = 0;
}
prefix prefix = new prefix(Ip,len);
list.add(prefix);
}
Collections.sort(list);
List<prefix> list1 = new ArrayList<prefix>();
//从小到大合并 从list找到合并后的元素放到list1里面
int size = list.size() - 1;
int min;
int[] ip1, ip2;
//k和k + 1匹配,能匹配则删掉k + 1,继续和新的k + 1匹配
int k = 0, nxt;//nxt指向第一个不能和k合并的值
while(k <= size) {
list1.add(list.get(k));
nxt = k + 1;
if(nxt > size) break;
while(nxt <= size) {
min = Math.min(list.get(k).len, list.get(nxt).len);
ip1 = and(list.get(k).ip,min);
ip2 = and(list.get(nxt).ip,min);
//取更小的长度min min之后的部分截掉变成0, 如果计算结果相同说明它们的匹配集相同
if(cmp(ip1, ip2) == 0)
nxt++;
else break;
}
k = nxt;
}
list.clear();
size = list1.size() - 1;
for(int i = 0; i <= size; i++){
list.add(list1.get(i));
}
//同级合并,永远从栈顶开始找
Stack<prefix> list2 = new Stack<prefix>();
size = list.size();
int compare = 1;
list2.push(list.get(0));
while(compare < size) {
prefix from = list2.pop();
prefix get = can_combine2(from, list.get(compare));
if(get == from) {
list2.push(from);
list2.push(list.get(compare));
compare++;
}
else {
list.set(compare, get);
if(list2.empty()) {
list2.push(list.get(compare));
compare++;
}
}
}
size = list2.size();
for(int i = 0; i < size; i++) list1.set(i, list2.pop());
list.clear();
for(int i = size - 1; i >= 0; i--) list.add(list1.get(i));
// in.close();
StringBuilder sb = new StringBuilder();
for(prefix show:list) {
sb.append(show.ip[0]+"."+show.ip[1]+
"."+show.ip[2]+"."+show.ip[3]+"/"+show.len + "\n");
}
sb.append(" ");
System.out.print(sb);
// for(prefix show:list) {
// System.out.println(show.ip[0]+"."+show.ip[1]+
// "."+show.ip[2]+"."+show.ip[3]+"/"+show.len);
// }
}
public static prefix can_combine2(prefix a, prefix b) {
//如果不能合并,返回a
if(a.len != b.len) return a;
int len = a.len - 1;
int[] ip1 = and(a.ip, len);
int[] ip2 = and(b.ip, len);
if(cmp(ip1, ip2) == 0) return new prefix(ip1, len);
else return a;
}
public static int cmp(int[] x, int[] y) {
for(int i = 0; i < 4; i++) {
if(x[i] > y[i])
return 1;
if(x[i] < y[i])
return -1;
}
return 0;
}
public static int cmp1(prefix a, prefix b) {
//判断a是否比b大, a > b返回1, a < b返回-1,a == b返回0
int[] x = a.ip;
int[] y = b.ip;
for(int i = 0;i < 4;i++) {
if(x[i] > y[i])
return 1;
else if(x[i] < y[i])
return -1;
}
if(a.len < b.len) return -1;
else if(a.len == b.len) return 0;
else return 1;
}
//获得一个前len位和p一样,后面为0的ip地址,用长度为4的数组表示
public static int[] and(int[] p, int len) {
int n = len / 8;
int m = len % 8;
int[] P = new int[4];
for(int i = 0; i < n; i++) P[i] = p[i];
//-1的二进制位全部是1,左移8-m位刚好使末尾8-m位是0
if(n<4) P[n] = p[n] & (-1 << (8 - m));
for(int i = n + 1; i < 4; i++) {
P[i] = 0;
}
return P;
}
}
4.数据中心
试题编号: 4
试题名称: 数据中心
时间限制: 1.0s
内存限制: 512.0MB
样例输入
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
样例输出
4
样例说明
下图是样例说明。
注意:子任务4中,n 改为5*104
c++代码(100分)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
int n, m, i, j, u, v, total;
int res = 0;
class Edge{
public:
int start,end;
int len;
};
Edge edge[500000];
int pre[100000];
long int ans=0;
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
int find(int x){
if(pre[x] == x){
return x;
}
else
{
pre[x]=find(pre[x]);
return pre[x];
}
}
bool cmp(Edge a, Edge b){
return a.len < b.len;
}
inline void kruskal(){
for(int i = 1; i <= m; i++){
u=find(edge[i].start);
v=find(edge[i].end);
cout<<u<<" "<<v<<endl;
if(u == v) continue;
ans += edge[i].len;
res = max(res, edge[i].len);
pre[u] = v;
total++;
if(total == n - 1) break;
}
}
int main(){
cin >> n >> m;//n是点的个数,m是边数
int root;
cin >> root;
for(i = 1; i <= n; i++)//顶点集合
pre[i] = i;
for(i = 1; i <= m; i++){//边集合
cin >> edge[i].start >> edge[i].end >> edge[i].len;
}
sort(edge+1,edge+m+1,cmp);//按照len值从小到大对edge排序
kruskal();
cout << res << endl;
return 0;
}
java代码(20分)
先写的c++,然后根据c++改的代码,不知道为啥只有二十分了
package csp15;
import java.util.Scanner;
class Edge {
public int start;
public int end;
public int len;
public Edge(){}
public Edge(int a,int b,int c){
start=a;
end=b;
len=c;
}
}
public class Main {
public static int max(int a,int b){
if(a>b)
return a;
else return b;
}
public static int find(int[] pre,int x){
if(pre[x] == x){
return x;
}else{
pre[x]=find(pre,pre[x]);
return pre[x];
}
}
public boolean cmp(Edge a, Edge b){
return a.len < b.len;
}
public static int kruskal(Edge[] edge,int[] pre,int m,int n,int res,int total,long ans){
int u,v;
for(int i = 1; i <= m; i++){
u=find(pre,edge[i].start);
v=find(pre,edge[i].end);
if(u == v) continue;
ans += edge[i].len;
res = max(res, edge[i].len);
pre[u] = v;
total++;
if(total == n - 1) break;
}
return res;
}
public static Edge[] sort(Edge[]edge,int m){
int a,b,c;
int j=0;
for(int i=1;i<=m-1;i++){
for(j=1;j<=m-i;j++){
if(edge[j].len>edge[j+1].len){
a=edge[j].start;
b=edge[j].end;
c=edge[j].len;
edge[j].start=edge[j+1].start;
edge[j].end=edge[j+1].end;
edge[j].len=edge[j+1].len;
edge[j+1].start=a;
edge[j+1].end=b;
edge[j+1].len=c;
}
}
}
return edge;
}
public static void main(String[] args) {
int n,m,i;
int res = 0;
int total=0;
long ans=0;
Edge edge[]=new Edge[500000];
Edge edge2[]=new Edge[500000];
int pre[]=new int[100000];
Scanner input=new Scanner(System.in);
n=input.nextInt();
m=input.nextInt();
//n是点的个数,m是边数
int root;
root=input.nextInt();
//System.out.println(n+" "+m+" "+root);
for(i = 1; i <= n; i++)//顶点集合
pre[i] = i;
for(i = 1; i <= m; i++){
edge[i]=new Edge();
}
for(i = 1; i <= m; i++){//边集合
edge[i].start=input.nextInt();
edge[i].end=input.nextInt();
edge[i].len=input.nextInt();
//System.out.println(edge[i].start+" "+edge[i].end+" "+edge[i].len);
}
edge2=sort(edge,m);//按照len值从小到大对edge排序
/*
for(i = 1; i <= m; i++){//边集合
System.out.println(edge2[i].start+" "+edge2[i].end+" "+edge2[i].len);
}*/
res=kruskal(edge2,pre,m,n,res,total,ans);
System.out.println(res);
input.close();
}
}
/*
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
*/
java代码(100分)
这个是转载的,不知道为啥他这个样例竟然没过,但却是100分
package csp15;
import java.awt.SystemColor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
List<int[]> allp = new ArrayList<>(); //接收m条边和其权值的列表
int ans = -1; //所需要的答案
int n = in.nextInt();
int m = in.nextInt();
int root= in.nextInt();
int[] nn = new int[n]; //n个点
for(int i=0;i<m;i++)
{
int[] mn= new int[3];
mn[0]=in.nextInt();
mn[1]=in.nextInt();
mn[2]=in.nextInt();
allp.add(mn);
}
Collections.sort(allp, new Comparator<int[]>() { //按权值排序
@Override
public int compare(int[] a,int[] b)
{
if(a[2]>b[2])
return 1;
else
return -1;
}
});
for(int i=0;i<allp.size();i++)
{
if(nn[allp.get(i)[1]-1]!=1||nn[allp.get(i)[0]-1]!=1) //判断此边的两个点是否已被连接
{
nn[allp.get(i)[1]-1]=1;
nn[allp.get(i)[0]-1]=1;
if(allp.get(i)[2]>ans) //更新最小树的最大权值
ans=allp.get(i)[2];
}
}
System.out.println(ans); //输出答案
}
}