7

//使用Cruskal解决问题

import java.util.Arrays;

import java.util.Comparator;

import java.util.Scanner;

//并查集实现最小生成树

public class Main{

private static class Edge{

//起点和终点

int x,y;

int weight;

public Edge(int x,int y,int weight)

{

this.x=x;

this.y=y;

this.weight=weight;

}

}

public static int father(int i,int a[])

{

int k=i;

while(a[k]!=k)k=a[k]; //并查集

return k;

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner in=new Scanner(System.in);

while(in.hasNext())

{

int n=in.nextInt();

int m=in.nextInt();

Edge[] edges=new Edge[m];

for(int i=0;i

{

edges[i]=new Edge(in.nextInt(),in.nextInt(),in.nextInt());

}

int a[]=new int[n+1];

for(int j=0;j<=n;j++)

{

a[j]=j;

}

Arrays.sort(edges,new Comparator() {

@Override

public int compare(Edge o1, Edge o2) {

// TODO Auto-generated method stub

return o1.weight-o2.weight;

}

});

int res=0;

for(int i=0;i

{

int px=father(edges[i].x,a);

int py=father(edges[i].y,a);

if(px!=py)

{

if(edges[i].weight>res)res=edges[i].weight;

if(px>py)

a[px]=py;

else

a[py]=px;

}

}

System.out.println(res);

}

}

}

发表于 2016-08-11 18:43:17

回复(5)

5

图的最小生成树 Prim算法或者Kruscal算法

下面给出Prim算法解法

如图所示 此例最小木材铺法如图最后步骤所示

此时最长木板为5

算法思想:

从V1出发 求出所有点中与V1的距离最短的一个节点V3(无法与V1直接相连的距离为无穷) 得到第一条边 然后在求剩下点到V1和V3的距离最近的点V6 依次类推直到所有点用完

注意:

为了减少时间复杂度引入数组dis[] dis[i]表示节点i到已连接的集合中所有点的最小距离

一开始时只有V1在集合中 所以dis[i]就为每个点到V1的距离 当V3也加入时 dis[i]要更新为

min(i到V1的距离, i到v3的距离)后面依次类推

这样可以将总的时间复杂度降为O(n^2) #include

#include

#include

#include

#include

#include

using namespace std;

const int maxn = 1e4 + 1;

const int MAX_INT = INT_MAX;

int dis[maxn];

int n, m, taken[maxn];

struct Node{

int to, val;

Node(int a, int b){

to = a;

val = b;

}

};

vector v[maxn];

int main(){

while(scanf("%d%d", &n, &m) == 2){

memset(taken, 0, sizeof(taken));

memset(dis, 0, sizeof(dis));

for(int i = 0; i < m; i++){

int a, b, val;

scanf("%d%d%d", &a, &b, &val);

v[a].push_back(Node(b, val));

v[b].push_back(Node(a, val));//用vector保存图

}

taken[1] = 1;//从点1开始

//由于鳄鱼的存在(即存在非联通分量 即存在从1出发永远到不了的点 所以必须从1出发 舍弃到不了的点)

for(int i = 1; i <= n; i++) dis[i] = MAX_INT;

for(int i = 0; i < v[1].size(); i++) dis[v[1][i].to] = v[1][i].val; //每个点到点1的距离

int ans = 0;

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

int min_val = MAX_INT, min_p;

for(int j = 1; j <= n; j++){//每个点到已连接集合的最短距离

if(!taken[j] && dis[j] < min_val){

min_val = dis[j];

min_p = j;

}

}

if(min_val == MAX_INT) continue;

ans = max(ans, min_val);

taken[min_p] = 1;

for(int j = 0; j < v[min_p].size(); j++){//更新dis数组

if(!taken[v[min_p][j].to] && v[min_p][j].val < dis[v[min_p][j].to])

dis[v[min_p][j].to] = v[min_p][j].val;

}

}

cout<

for(int i = 0; i < n; i++) v[i].clear();

}

return 0;

}

/*

4 3

1 2 1

2 3 1

3 4 2

ans: 2

5 4

1 2 3

1 3 8

2 3 2

4 5 7

ans: 3

*/

编辑于 2018-10-28 15:50:00

回复(0)

5

//循边最小生成树,并查集动态查询连通性

include

#include

#include

#include

#include

using namespace std;

int father(int i, vector &UF)

{

int k=i;

while(UF[k]!=k)k=UF[k];

return k;

}

int main()

{

int N,M;

while(cin>>N>>M)

{

multimap> cost;

while(M--)

{

int a,b,c;

cin>>a>>b>>c;

cost.insert(make_pair(c,make_pair(min(a,b),max(a,b))));

}

vectorUF(N+1);

for(int i=0;i<=N;i++)

UF[i]=i;

int maxV = -1;

int cc = 0;

for(auto it=cost.begin();it!=cost.end();it++)

{

int px = father(it->second.first,UF);

int py = father(it->second.second,UF);

if(px != py)

{

cc++;

if(it->first>maxV)maxV=it->first;

UF[px] = UF[py];

}

}

cout<

};

return 0;

}

编辑于 2016-08-20 09:03:46

回复(2)

8

有没有大牛讲下题目意思,我看不大懂

发表于 2018-03-16 19:25:34

回复(3)

2

本套6道题全部pass的C++代码已挂到了我的GitHub(https://github.com/shiqitao/NowCoder-Solutions)

牛客网上的其他题目解答也在持续更新。

【题解】贪心算法:每次添加最短的木块,直到全连通。使用并查集判断动态连通性。 #include

#include

using namespace std;

struct Wood

{

unsigned short int P, Q, K;

};

bool cmp(Wood wood1, Wood wood2);

int find(int *set, int x);

int main()

{

int N, M; cin >> N >> M;

Wood *wood = new Wood[M];

int maxLen = 0;

for (int i = 0; i < M; i++) {

cin >> wood[i].P >> wood[i].Q >> wood[i].K;

wood[i].P -= 1;

wood[i].Q -= 1;

}

sort(wood, wood + M, cmp);

int *set = new int[N];

for (int i = 0; i < N; i++) {

set[i] = i;

}

for (int i = 0; i < M; i++) {

int fx = find(set, wood[i].P);

int fy = find(set, wood[i].Q);

set[fx] = fy;

int cnt = 0;

for (int i = 0; i < N; i++) {

cnt += set[i] == i ? 1 : 0;

}

if (cnt == 1) {

cout << wood[i].K;

delete[] wood;

return 0;

}

}

}

bool cmp(Wood wood1, Wood wood2)

{

return wood1.K < wood2.K;

}

int find(int *set, int x){

return x == set[x] ? x : (set[x] = find(set, set[x]));

}

发表于 2018-03-20 11:29:18

回复(1)

1

如果用prime,图的构建用邻接矩阵会超限,请用邻接表 package com.special.first;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Scanner;

/**

* 楚楚街02-寻宝

*

* 最小生成树,保留最大的边的即可

* prime算法,不过我用邻接矩阵超内存限制了,后改用邻接表

*

* Create by Special on 2018/3/9 10:26

*/

public class Pro057 {

static final int MAX = Integer.MAX_VALUE;

static final int MIN = Integer.MIN_VALUE;

// public static int getMaxTree(int N, int[][] costs){

// int[] prices = new int[N];

// Arrays.fill(prices, MAX);

// boolean[] visited = new boolean[N];

// for(int i = 0; i < N; i++){

// if(costs[0][i] != MAX){

// prices[i] = costs[0][i];

// }

// }

// visited[0] = true;

// int index, min, maxTree = MIN;

// for(int i = 1; i < N; i++){

// index = -1;

// min = MAX;

// for(int j = 1; j < N; j++){

// if(!visited[j] && prices[j] < min){

// index = j;

// min = prices[j];

// }

// }

// maxTree = Math.max(maxTree, min);

// visited[index] = true;

// for(int j = 1; j < N; j++){

// if(!visited[j] && costs[index][j] != MAX

// && costs[index][j] < prices[j]){

// prices[j] = costs[index][j];

// }

// }

// }

// return maxTree;

// }

static class Node{

int drc;

int cost;

public Node(int drc, int cost){

this.drc = drc;

this.cost = cost;

}

}

public static int getMaxTree(int N, ArrayList[] costs) {

int[] prices = new int[N];

Arrays.fill(prices, MAX);

boolean[] visited = new boolean[N];

for (int i = 0; i < costs[i].size(); i++) {

prices[costs[i].get(i).drc] = costs[i].get(i).cost;

}

visited[0] = true;

int index, min, maxTree = MIN;

for (int i = 1; i < N; i++) {

index = -1;

min = MAX;

for (int j = 1; j < N; j++) {

if (!visited[j] && prices[j] < min) {

index = j;

min = prices[j];

}

}

maxTree = Math.max(maxTree, min);

visited[index] = true;

ArrayList head = costs[index];

int drc;

for (int j = 0; j < head.size(); j++) {

drc = head.get(j).drc;

if (!visited[drc]) {

prices[drc] = Math.min(prices[drc], head.get(j).cost);

}

}

}

return maxTree;

}

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

while(input.hasNext()){

int N = input.nextInt();

int M = input.nextInt();

// int[][] costs = new int[N][N];

ArrayList[] costs = new ArrayList[N];

for(int i = 0; i < N; i++){

costs[i] = new ArrayList<>();

}

int src, drc, cost;

while(M-- > 0){

src = input.nextInt() - 1;

drc = input.nextInt() - 1;

cost = input.nextInt();

costs[src].add(new Node(drc, cost));

costs[drc].add(new Node(src, cost));

}

System.out.println(getMaxTree(N, costs));

}

}

}

发表于 2018-03-09 11:24:07

回复(0)

1

没有想到最小生成树,用的DFS,超时。

#include

using namespace std;

unordered_map>> umap;

bool visited[10001];

unsigned long long sum = 0;

int maxK = -1, premaxK = -1, ans = -1;

bool isLeaf = false;

void dfs(int N, int pos, int count) {

if(count == N-1) {

cout << "sum = " << sum << endl;

ans = max(ans, maxK);

maxK = premaxK;

return;

}

bool flag = false;

for(int i = 0; i < umap[pos].size(); ++i) {

if(!visited[umap[pos][i].first]) {

flag = true;

visited[umap[pos][i].first] = true;

sum += umap[pos][i].second;

premaxK = maxK;

maxK = max(maxK, umap[pos][i].second);

dfs(N, umap[pos][i].first, count+1);

if (isLeaf) {

isLeaf = false;

sum += umap[pos][i].second;

count += 1;

dfs(N, pos, count);

count -= 1;

maxK = premaxK;

visited[umap[pos][i].first] = false;

sum -= 2*umap[pos][i].second;

} else {

maxK = premaxK;

visited[umap[pos][i].first] = false;

sum -= umap[pos][i].second;

}

}

}

if(!flag) {

isLeaf = true;

}

}

int main() {

int N, M;

while (cin >> N >> M) {

//memset(table, 0, sizeof(table));

memset(visited, 0, sizeof(visited));

for (int i = 0; i < M; ++i) {

int P, Q, K; cin >> P >> Q >> K;

//table[P-1][Q-1] = K;

//table[Q-1][P-1] = K;

umap[P-1].push_back(make_pair(Q-1, K));

umap[Q-1].push_back(make_pair(P-1, K));

}

visited[0] = true;

dfs(N, 0, 0);

cout << ans << endl;

}

return 0;

}

最小生成树代码:

int bin[10001];

void init() {

for (int i = 0; i <= 10000; i++) {

bin[i] = i;

}

}

int findx(int x) {

int r = x;

while ( r != bin[r]) r = bin[r];

return r;

}

int main() {

int n, m;

while (cin >> n >> m) {

multimap> mmap;

for (int i = 0; i < m; i++) {

int p, q, k; cin >> p >> q >> k;

mmap.insert(make_pair(k, make_pair(min(p, q), max(p, q))));

}

init();

int maxK = -1;

for (auto &item : mmap) {

int fx = findx(item.second.first);

int fy = findx(item.second.second);

if (fx != fy) {

bin[fy] = fx;

maxK = max(maxK, item.first);

}

}

cout << maxK << endl;

}

return 0;

}

不过值得注意的是,默认输入数据是保证图是联通的,如果输入数据使得图不连通,那么此时需要对这些特殊输入作处理,比如输出-1啥的,表示不可到达。不过测试用例没有这种不连通的输入。建议加上这些测试用例。

修改后的代码如下:

int bin[10001];

bool mark[10001];

void init() {

for (int i = 0; i <= 10000; i++) {

bin[i] = i;

mark[i] = false;

}

}

int findx(int x) {

int r = x;

while ( r != bin[r]) r = bin[r];

return r;

}

int main() {

int n, m;

while (cin >> n >> m) {

multimap> mmap;

for (int i = 0; i < m; i++) {

int p, q, k; cin >> p >> q >> k;

mark[p] = mark[q] = true;

//mmap.insert(make_pair(k, make_pair(min(p, q), max(p, q))));

mmap.insert(make_pair(k, make_pair(p, q)));

}

init();

int maxK = -1;

for (auto &item : mmap) {

int fx = findx(item.second.first);

int fy = findx(item.second.second);

if (fx != fy) {

bin[fy] = fx;

maxK = max(maxK, item.first);

}

}

int cc = 0;

for(int i = 1; i <= 10000; i++) {

if (bin[i] == i && mark[i]) cc++;

}

if (cc > 1)

cout << "invalid input" << endl;

else

cout << maxK << endl;

}

return 0;

}

编辑于 2017-05-11 16:03:59

回复(0)

1

#include

using namespace std;

int parent(int i, vector &a)

{ int k = i; while(a[k] != k) k = a[k]; return k;

}

int main()

{ int N,M; while(cin>>N>>M) { multimap> cost; while(M--) { int p,q,k; cin>>p>>q>>k; cost.insert(make_pair(k, make_pair(min(p,q), max(p,q)))); } vector a(N+1); for(int i=0;i<=N;i++) a[i] = i; int maxV = -1; for(auto it=cost.begin();it!=cost.end();it++) { int px = parent(it->second.first, a); int py = parent(it->second.second, a); if(px != py) { if(it->first > maxV) maxV = it->first; a[px] = a[py]; } } cout<

}

发表于 2017-11-28 00:55:21

回复(0)

1

import java.util.Scanner;

public class Main {

public static class Dis{

int index; //空地的起点

int dis; //空地的终点

int pre; //两块空地之间的距离

}

public static void main(String args[]){

Scanner cin = new Scanner(System.in);

while(cin.hasNext()){

int n = cin.nextInt();

int m = cin.nextInt();

Dis map[] = new Dis[m];

for(int i = 0;i < m;i++){

map[i] = new Dis(); //每次进入的元素插入队尾

map[i].index = cin.nextInt();

map[i].pre = cin.nextInt();

map[i].dis = cin.nextInt();

for(int j = i;j > 0;j--){ //使用冒泡排序,对新插入的元素插入队列

if(map[j].dis < map[j-1].dis){

int index = map[j].index;

int pres = map[j].pre;

int dis = map[j].dis;

map[j].index = map[j-1].index;

map[j].pre = map[j-1].pre;

map[j].dis = map[j-1].dis;

map[j-1].index = index;

map[j-1].pre = pres;

map[j-1].dis = dis;

}else

break; //队列已经有序了,跳出循环

}

}

int Point[][] = new int[n+1][2]; //所有点的集合为图集,Point[i][0]表示点是否进入,Point[i][1]表示点所属类别

int max_dis = 0; //记录最大距离

int sum_point = 0; //记录有多少点进入了图集

int EquNum = 0; //标记等价类的个数

int mst[] = new int[n]; //标记进入图集的点的分类

int flag = 0; //记录已有进入的多少类了,合并之后不删除

for(int i = 0;i < m;i++){

if(sum_point == n && EquNum == 1)

break; //所有点都进入了点集,并且所有点都属于同一类了

if(Point[map[i].index][0] == 0 && Point[map[i].pre][0] == 0 ){//这两个点都没在图集中,

flag++;

EquNum++;

Point[map[i].index][1] = flag;

Point[map[i].pre][1] = flag;

mst[flag] = flag;

Point[map[i].index][0] = 1;

Point[map[i].pre][0] = 1;

max_dis = map[i].dis;

sum_point++;

sum_point++;

}else if(Point[map[i].pre][0] == 0 && Point[map[i].index][0] == 1){

Point[map[i].pre][0] = 1;

Point[map[i].pre][1] = Point[map[i].index][1];

max_dis = map[i].dis;

sum_point++;

}else if(Point[map[i].pre][0] == 1 && Point[map[i].index][0] == 0){

Point[map[i].index][0] = 1;

Point[map[i].index][1] = Point[map[i].pre][1];

max_dis = map[i].dis;

sum_point++;

}else{

if(mst[Point[map[i].index][1]] != mst[Point[map[i].pre][1]]){

max_dis = map[i].dis;

if(mst[Point[map[i].index][1]] > mst[Point[map[i].pre][1]]){

mst[Point[map[i].index][1]] = mst[Point[map[i].pre][1]];

}else

mst[Point[map[i].pre][1]] = mst[Point[map[i].index][1]];

EquNum--;

}

}

}

System.out.println(max_dis);

}

}

答案错误:您提交的程序没有通过所有的测试用例

case通过率为50.00%

测试用例:

4386 7121

1800 51 82

402 98 24

602 4049 100

341 3043 79

742 1692 40

3933 449 3

142 2747 3

2213 1905 73

4027 751 80

3398 3971 11

2813 1577 69

826 2150 35

3053 935 54

2043 585 39

31 3348 44

3355 1642 31

3120 2574 58

854 1803 39

1202 229 76

1944 1746 15

4034 3972 93

1327 3872 45

1363 2429 38

3042 1545 55

2770 3058 64

1055 2333 74

4357 1929 25

240 1167 45

。。。。

我是用的Kruskal算法来实现的,各位大神帮忙看看,这个测试用例没有过,但是个人感觉我的逻辑应该是没有错的,求解答

编辑于 2016-05-21 12:27:27

回复(1)

0

#include

using namespace std;

struct node{

int u,v;

int weight;

node(int u_,int v_,int w){

u = u_;v=v_;weight=w;

}

node(){}

};

vectorfa;

maprank_;

int find(int x)

{

while(x!=fa[x])

x = fa[x];

return x;

}

bool union_(int x,int y)

{

int fa_x = find(x);

int fa_y = find(y);

if(fa_x!=fa_y)

{

int big = rank_[fa_x] > rank_[fa_y] ? fa_x : fa_y;

int small = big==fa_x ? fa_y : fa_x;

fa[small] = big;

rank_[big] += rank_[small];

rank_.erase(small);

return true;

}

return false;

}

bool cmp(node& a,node& b)

{

return a.weight

}

int main()

{

// 任何一块空地都要可达 就是得求一个连通块

// 连通块里最长的那条边尽可能小 即最小生成树

// kruskal

int n,m;

while(cin>>n>>m)

{

fa.resize(n+1);

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

{

fa[i] = i;

rank_[i] = 1;

}

vectorv;

for(int i=0;i

{

int a,b,c;

cin>>a>>b>>c;

v.push_back(node(a,b,c));

}

//cout<

sort(v.begin(),v.end(),cmp);

int k = 0;

int Max = 0;

//for(auto t:v)

// cout<

for(int i=0;i

{

if(union_(v[i].u,v[i].v))

{

Max = max(Max,v[i].weight);

++k;

}

if(k==n-1)

break;

}

cout<

}

return 0;

}

发表于 2020-04-18 15:44:42

回复(0)

0

#问题转化成求图的最小生成树,输出最小生成树里权值最大的边,Kruskal算法

import collections

def find(x):#并查集

while x!=uni[x]:

x=uni[x]

return x

N,M=list(map(int,input().split()))

land=[list(map(int,input().split())) for i in range(M)]

land=sorted(land,key=lambda x:x[2])

uni=list(range(N+1))

count=0

for line in land:

s,e,v=line#起点,终点,权值

if s>e:

s,e=e,s

s=find(s)

e=find(e)

if s==e:

continue

else:

uni[e]=s

count+=1

if count==N-1:

print(v)

break

发表于 2018-10-01 16:36:32

回复(1)

0

暴力版的PRIM算法超时,只能过50%,所以用了简化版的并查集+Kruskal算法

Python代码如下 try:

def findx(x):

while x != uni[x]:

x = uni[x]

return x

while 1:

import collections

N,M = [int(x) for x in input().split()]

m_list = []

for i in range(M):

temp = [int(x) for x in input().split()]

m_list.append(temp)

uni = [i for i in range(N+1)]

m_list = sorted(m_list,key=lambda x:x[2])

v_count = 0

for line in m_list:

s,e,v = line

if s>e:

s,e = e,s

set_s = findx(s)

set_e = findx(e)

if set_e==set_s:

continue

else:

uni[set_e] = set_s

v_count+=1

if v_count==N-1:

print(v)

break

except EOFError:

pass

发表于 2018-07-04 14:10:01

回复(0)

0

楚楚街的出题人可能是文盲,出的题都很难理解,自己想要的东西都说不清楚,下面的人怎么执行。

发表于 2018-06-11 13:51:02

回复(1)

0

发表于 2018-04-15 23:32:25

回复(0)

0

题目说的是有n个空地,每个空地之间需要用一定长度的木材连接,求需要木材长度最少的方案。n个空地和空地间的木材构成一个图,求图的最小生成树即可。题目有一点没说清楚,它要求耗费木材最少,我想是的耗费的木材根数最少,结果一直认为要求最少边的生成树,然后就遍历导致超时了。

更多牛客网题解代码在https://github.com/ReyzalX/nowcoder查看。 #include

usingnamespacestd;

structArc

{

intb, e;

intcost;

};

intmain()

{

//求最小生成树即可

intN, M;

cin >> N >> M;

vector data(M);

//树的集合

vector> tree(N);

for(inti = 0; i < M; i++)

{

cin >> data[i].b >> data[i].e >> data[i].cost;

}

for(inti = 0; i < N; i++)

{

tree[i].push_back(i + 1);

}

sort(data.begin(), data.end(), [](Arc& c1, Arc& c2) {returnc1.cost < c2.cost; });

intlongestWood = 0;

for(inti = 0; i < M; i++)

{

intb = data[i].b;

inte = data[i].e;

intbIndex = -1;

inteIndex = -1;

for(inti = 0; i < N; i++)

{

if(find(tree[i].begin(),tree[i].end(),b) != tree[i].end())

{

bIndex = i;

}

if(find(tree[i].begin(), tree[i].end(), e) != tree[i].end())

{

eIndex = i;

}

}

if(bIndex == eIndex)

{

//已经在同一个集合中

continue;

}

tree[bIndex].insert(tree[bIndex].end(), tree[eIndex].begin(), tree[eIndex].end());

tree[eIndex].clear();

longestWood = max(longestWood, data[i].cost);

}

cout << longestWood << endl;

return0;

}​

发表于 2018-03-26 10:11:13

回复(0)

0

哪位大神帮我看看我的哪里错了!!!!!!!!!!拜托拜托!!!!!!!

import java.util.Scanner;

/**

* 最小生成树知识点

* @author yg

*

*/

public class LongMood {

/**输入描述:第一行包含两个整数N(1≤N≤10000),M(1≤M≤1000000)。N表示公有N块空地。

*        接下来M行,每行包含三个整数P(1≤P≤N),Q(1≤Q≤N),K代表P,Q两个间没有鳄鱼,需要耗费K的木材。

*输出描述:一个整数,即耗费木材最少的情况下,最长的那根木材长度

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

int max=0;

int min=0;

System.out.println("请输入空地N和行数M的值:");

Scanner input = new Scanner(System.in);

int n=input.nextInt();

int m=input.nextInt();

int [][]arr=new int[m][3];

System.out.println("输入各个元素:");

for(int i=0;i

for(int j=0;j<3;j++){

arr[i][j]=input.nextInt();

}

}

//    for(int j=0;j<3;j++){

for(int i=0;i

min=i;//每轮查找最小数的下标

for(int h=i+1;h

if(arr[min][2]>arr[h][2]){

min=h;//保存最小数的下标

}

}

if(i!=min){

int temp0 = arr[i][0];

arr[i][0]=arr[min][0];

arr[min][0]=temp0;

int temp1 = arr[i][1];

arr[i][1]=arr[min][1];

arr[min][1]=temp1;

int temp2 = arr[i][2];

arr[i][2]=arr[min][2];

arr[min][2]=temp2;

}

}

//    }

StringBuffer sbu=new StringBuffer();

for(int i=0;i

for(int j=0;j<2;j++){

String str=Integer.toString(arr[i][j]);

if(sbu.indexOf(str)<0){

sbu.append(str);

if(sbu.length()==n){

System.out.println(arr[i][2]);

break;

}

}

}

}

System.out.println(sbu);

/*    for(int i=0;i

for(int j=0;j<3;j++){

System.out.print(arr[i][j]+" ");

}

System.out.println();

}*/

//1 2 8 1 6 7 1 5 5 2 6 2 2 3 1 3 6 4 3 4 3 4 6 2 4 5 1 5 6 4

}

}

发表于 2018-03-21 21:47:10

回复(0)

0

没人说一下这个题是什么意思吗?什么鬼完全没看懂

发表于 2018-03-19 10:40:07

回复(0)

0

#include

#include

#include

#include

using namespace std;

typedef struct Node

{

int p;

int q;

int k;

}node;

vector pre;

int unionsearch(int index) {

while (pre[index] != index) {

pre[index] = pre[pre[index]];

index = pre[index];

}

return index;

}

void join(int x, int y) {

if (pre[x] != pre[y]) {

pre[x] = y;

}

}

bool cmp(const node& vn1, const node & vn2) {

return vn1.k < vn2.k;

}

int main(void) {

int N, M;

scanf("%d %d", &N, &M);

vector vn;

for (int i = 0; i < M; i++) {

node tmp;

scanf("%d %d %d", &tmp.p, &tmp.q, &tmp.k);

vn.push_back(tmp);

}

// initialize union set;

for (int i = 0; i <= N; i++) {

pre.push_back(i);

}

sort(vn.begin(), vn.end(), cmp);

int res = 0;

for (int i = 0; i < M; i++) {

int rootA = unionsearch(vn[i].p);

int rootB = unionsearch(vn[i].q);

if (rootA != rootB) {

if (res < vn[i].k) {

res = vn[i].k;

}

join(rootA, rootB);

}

}

cout << res << endl;

return 0;

}

发表于 2018-03-15 14:34:56

回复(0)

0

哪位大神 帮我看看 为什么AC   50%--------------------------

4386 7121

1800 51 82

402 98 24

602 4049 100

341 3043 79

742 1692 40

3933 449 3

142 2747 3

...  ..  ...   ... import java.util.Arrays;

import java.util.Comparator;

import java.util.Scanner;

public class Main{

private static class Edge{

//边  起点和终点

int x,y;

int weight;  //权值

public Edge(int x,int y,int weight)

{

this.x=x;

this.y=y;

this.weight=weight;

}

}

public static void main(String[] args) {

Scanner s=new Scanner(System.in);

while(s.hasNext()){

int n=s.nextInt();

int m=s.nextInt();

Edge []e=new Edge[m];//边 集合

int  []liantong=new int[n+1]; //连通分量  之后初始时 有  n 个连通分量

//初始化连通数组

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

liantong[i] = i;

}

//初始化边数组

for(int i=0 ; i

e[i]=new Edge(s.nextInt(),s.nextInt(),s.nextInt());

}

//权值从小到大 排序

Arrays.sort(e, new Comparator() {

@Override

public int compare(Edge o1, Edge o2) {

return o1.weight>o2.weight ? 1 : -1/*(o1.weight

}

});

//for(int i=0 ; i

//   System.out.println(e[i].weight+" ");

//}

int res=0;

//每次选中 剩余最小权重边  加入

boolean unionLiantong = true;//true ,表示继续选边 添加

for(int i=0;i

/*  int px = findParent(liantong,e[i].x);

int py = findParent(liantong,e[i].y);

if(px!=py){

if(e[i].weight>res)

res = e[i].weight;

//合并连通分量,可以考虑根据树的的高度,选择合并方向

if(px>py)

liantong[px]=py;

else

liantong[py]=px;

}*/

//两端节点 已在同一连通变量的边 不考虑

if(liantong[e[i].x] != liantong[e[i].y]){

//System.out.println("选中边--"+e[i].weight);

unionLiantong = unionLiantong(liantong, e[i].x, e[i].y);

res=Math.max(res, e[i].weight);

if(unionLiantong == false){

break;

}

//  System.out.println(Arrays.toString(liantong));

}

}

System.out.println(res);

}

}

private static boolean unionLiantong(int[] liantong, int x,int y){

int temp1=Math.min(liantong[x],liantong[y]); //方向往小 修改   (小值)

int temp2; //(大值)

if(temp1!=liantong[x]) temp2=liantong[x]; else temp2=liantong[y];

for(int i =1 ; i

if(liantong[i]==temp2)   //把 所有与此点 同属一个连通分量组 中的 节点全 修改值,把2个连通分量组变成同1个连通分量组

liantong[i]=temp1;

}

return !is_one_liantong(liantong);

//返回值,是一个连通分量的话, 不再添加 边,  返回false

//不是一个连通分量的话,继续添加 边      返回true

}

private static boolean is_one_liantong(int[] liantong) {

for(int i=1 ;i

if(liantong[i]!=liantong[i+1]){

//              System.out.println("不为1个连通分量!");

return false;

}

}

//        System.out.println("只有一个连通分量");

return true;

}

}

发表于 2017-10-29 12:02:24

回复(0)

0

#include

#include

using namespace std;

const int INF = INT32_MAX;

struct Node {

int next;

int cost;

Node(){

cost=INF;

}

Node(int n, int c) {

next = n;

cost = c;

}

};

int main() {

int N,M;

while (cin >> N>>M) {

vector> map(N + 1);

for (int i = 0;i

int P, Q, K;

cin >> P >> Q >> K;

Node node1(Q,K), node2(P,K);

map[P].push_back(node1);

map[Q].push_back(node2);

}

vector cost(N + 1, INF), visited(N + 1, 0), previous(N + 1);

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

previous[i] = i;

visited[1] = 1;

for (int i = 0;i

int pos = map[1][i].next;

cost[pos] = map[1][i].cost;

previous[pos] = 1;

}

for (int i = 2;i

int min = INF, pos;

for (int i = 1;i

if ((visited[i] == 0) && (cost[i]

min = cost[i];

pos = i;

}

}

visited[pos] = 1;

for (int j = 0;j

int p = map[pos][j].next;

if ((visited[p] == 0) && ((min+ map[pos][j].cost)

cost[p] = min + map[pos][j].cost;

previous[p] = pos;

}

}

}

int max = 0, now = N, pre = previous[now];

while (pre != now) {

int c;

for (int i = 0;i

if (map[pre][i].next == now) {

c = map[pre][i].cost;

break;

}

}

if (c>max)

max = c;

now = pre;

pre = previous[pre];

}

cout << max << endl;

}

return 0;

}

发表于 2017-06-14 13:36:27

回复(1)

java寻宝题目,寻宝相关推荐

  1. 2021年Java面试题目最新总结【90%面试会踩的坑】

    学会java技术之后大家面临的最多的问题就是面试这关,求职面试java岗位是否能够成功是直接影响我们的工作机会的,所以对于Java程序员面试你准备好了吗?今天小编汇总了一下关于Java程序员面试,90 ...

  2. java职业教育考试题_Java认证考试中Java构造方法题目解答

    [Java认证考试中Java构造方法题目解答]java中,在创建一个新的对象的时候,会调用其父亲的构造方法,测试程序如下: class parent{ int a=5; public parent() ...

  3. 2019蚂蚁金服 Java面试题目!涵盖现场3面真题

    蚂蚁Java一面 二叉搜索树和平衡二叉树有什么关系,强平衡二叉树(AVL树)和弱平衡二叉树(红黑树)有什么区别 B树和B+树的区别,为什么MySQL要使用B+树 HashMap如何解决Hash冲突 e ...

  4. 非常全面的阿里的Java面试题目,涵盖Java基础+高级+架构

    阿里技术一面 自我介绍 Java中多态是怎么实现的 Java中的几种锁 数据库隔离级别 脏读 幻读 ACID mysql的隔离级别 mysql索引实现,如何解决慢查询 数据库锁是怎么实现的 死锁的条件 ...

  5. 史上最全阿里Java面试题目大汇总!强烈建议收藏~

    阿里面试题目目录 技术一面(基础面试题目) 技术二面(技术深度.技术原理) 项目实战(项目模拟面试) JAVA开发技术常问的问题 阿里必会知识 阿里面试范畴 阿里面试总结 一:阿里技术一面(基础掌握牢 ...

  6. 最全蚂蚁金服高级Java面试题目(3面)

    一面: JVM数据存储模型,新生代.年老代的构造? java GC算法,什么时候会触发minor gc,什么时候会触发full gc? GC 可达性分析中哪些算是GC ROOT? 你熟悉的JVM调优参 ...

  7. 阿里巴巴Java面试题目

    [应聘]阿里巴巴Java面试题目 原文地址:http://blog.csdn.net/free0sky/article/details/7927275 见过的很全的Java知识总结,强悍的人生不需要解 ...

  8. java毕业设计题目

    java毕业设计题目第一部分 班级风采网站的设计 简易博客网站的设计与实现 工资绩效管理系统的开发 电子产品销售网站的设计与实现 酒店预订信息管理系统的设计 成绩管理系统 B2C电子商务平台 B2C的 ...

  9. Java变态题目(持续更新)

    java变态题目(持续更新) 文章目录 java变态题目(持续更新) java常识·归档int 第一题 第二题 第三题 java常识·归档String 第一题 第二题 第三题 java常识·归档Lis ...

最新文章

  1. 编写同时在PyTorch和Tensorflow上工作的代码
  2. CocoaPods的安装失败方法
  3. svn 面板缺少可选项_TortoiseSVN的设置
  4. L1-003 个位数统计
  5. MAVEN_OPTS=-Xms128m -Xmx512m
  6. java grpc protobuf_protobuf+grpc+examples
  7. 指针和指针的指针_网络上的iPad指针
  8. mysql查询今天_昨天_7天_近30天_本月_上一月 数据_mysql查询今天、昨天、7天、近30天、本月、上一月 数据...
  9. smarty模板基础
  10. 除冰机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  11. 流水灯及注释c语言,流水灯 - 单片机教程 - C语言网
  12. Kotlin中文教程
  13. 考研高等数学张宇30讲笔记——第一讲 高等数学预备知识
  14. 如何快速翻译医学类英文专业文献?
  15. 如何将dom转化为pdf
  16. 单模光电转换器怎么接_光纤收发器及其连接方式图解!
  17. PPT:PowerPoint to Flash SDK:SWF
  18. Saliency map (fixation map) 生成热点图-python实现
  19. 关于计算机的英语单词及例句,小学生必背英语单词及例句(四年级).doc
  20. Wireshark抓包页面的登录信息

热门文章

  1. 跟这台计算机连接的一个USB设备运行不正常,Windows无法识别
  2. python学生管理系统用列表_史上最全面的python学生管理系统教程(二)
  3. [2021.11.19]UPC-2021级新生个人训练赛第4场-19278 Problem D 关门
  4. 上了年纪的酒店,如何“鸟枪换炮”?
  5. 微信小程序wx.base64ToArrayBuffer调用,提示thirdScriptError atob failed;undefined Error: atob failed
  6. Voting Disks的管理
  7. 从Eclipse官网查找自己要的插件地址 来安装
  8. SPSS如何使用基础功能?
  9. ArrayList和LinkedList的底层源码之我见
  10. 微信小程序开发-多条件搜索tab展示