FZu Problem 2233 ~APTX4869 (并查集 + sort)

题目链接:

  FZu Problem 2233 ~APTX4869

题目描述:

  给一个n*n的矩阵,(i, j)表示第 i 种材料 和 第 j 种材料的影响值,这个矩阵代表这n个物品之间的影响值。当把这n个物品分成两部分后,每部分内部材料不会相互影响,但是不同部分的材料之间会相互影响。问如何分割使得两部分材料相互之间的最小影响值最大?

解题思路:

  材料内部不会影响,那么只需要把影响值小的物品放在同一部分即可,所以用结构体保存物品之间的影响值,然后sort一下,影响值小的物品用并查集放在一个集合,当集合等于2的时候,遍历到物品分别在不同集合的影响值就是ans。

 1 #include <cstdio>
 2 #include <queue>
 3 #include <stack>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9
10 #define lson 2*root
11 #define rson 2*root+1
12 typedef __int64 LL;
13 const LL mod = 1000000007;
14 const LL INF= 1e9+7;
15 const int maxn = 810;
16
17 struct node
18 {
19     int x, y, z;
20 }a[maxn*maxn];
21 int vis[maxn];
22 bool cmp (node a, node b)
23 {
24     return a.z < b.z;
25 }
26
27 void init ()
28 {
29     for (int i=0; i<maxn; i++)
30         vis[i] = i;
31 }
32
33 int find (int x)
34 {
35     if (vis[x] != x)
36         vis[x] = find(vis[x]);
37     return vis[x];
38 }
39 int main ()
40 {
41     int n;
42     while (scanf ("%d", &n) != EOF)
43     {
44         init ();
45         int m = 0;
46         for (int i=0; i<n; i++)
47             for (int j=0; j<n; j++)
48             {
49                 scanf ("%d", &a[m].z);
50                 if (i < j)
51                  {
52                     a[m].x = i;
53                     a[m ++].y = j;
54                  }
55             }
56         sort (a, a+m, cmp);
57
58         int ans = INF, cnt = n;
59         for (int i=0; i<m; i++)
60         {
61             int x = find (a[i].x);
62             int y = find (a[i].y);
63
64             if (x == y)
65                 continue;
66
67             if (x != y && cnt > 2)
68             {
69                 vis[x] = y;
70                 cnt --;
71             }
72             else
73                 ans = min (ans, a[i].z);
74
75             if (ans != INF)
76                 break;
77         }
78
79         printf ("%d\n", ans);
80     }
81     return 0;
82 }
83
84 /*
85 4
86 -1 100 200 300
87 100 -1 400 500
88 200 400 -1 600
89 300 500 600 -1
90 */
时间: 2024-10-14 18:54:38

FZu Problem 2233 ~APTX4869 (并查集 + sort)的相关文章

Problem 2233 ~APTX4869

Problem 2233 ~APTX4869 Accept: 55    Submit: 176Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 为了帮助柯南回到一米七四,阿笠博士夜以继日地研究APTX4869的解药.他得出了如下结果: 1.解药由n种原料构成: 2.对于两种不同的的原料a,b,它们之间有个影响值f(a,b): 3.需要把原料分成两个部分X,Y,每部分中至少有一种原料: 4.解药的效果由分别属

ZOJ Problem Set - 3321 并查集

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3321 Circle Time Limit: 1 Second      Memory Limit: 32768 KB Your task is so easy. I will give you an undirected graph, and you just need to tell me whether the graph is just a circle.

ACM: FZU 2112 Tickets - 欧拉回路 - 并查集

FZU 2112 Tickets Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Practice Description You have won a collection of tickets on luxury cruisers. Each ticket can be used only once, but can be used in either direction between

*并查集的题*

POJ 1182 食物链http://acm.pku.edu.cn/JudgeOnline/problem?id=1182题目告诉有3种动物,互相吃与被吃,现在告诉你m句话,其中有真有假,叫你判断假的个数(如果前面没有与当前话冲突的,即认为其为真话)这题有几种做法,我以前的做法是每个集合(或者称为子树,说集合的编号相当于子树的根结点,一个概念)中的元素都各自分为A, B, C三类,在合并时更改根结点的种类,其他点相应更改偏移量.但这种方法公式很难推,特别是偏移量很容易计算错误.下面来介绍一种通用

最小生成树(kruskal+并查集)

最小生成树 最小生成树即用最少的边权将所有给定的点连在同一联通分量中,常用kruskal和prim算法 kruskal算法(适合稀疏图) 最小生成树的kruskal算法,稍带并查集的应用 int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); //不要漏了fa[x]=... } int kruskal() { int ans=0; for(int i=0;i<N;i++) fa[i]=i;//初始化并查集 sort(edge,edge+e);

【POJ - 1703】Find them, Catch them(种类并查集)

Find them, Catch them 直接翻译了 Descriptions 警方决定捣毁两大犯罪团伙:龙帮和蛇帮,显然一个帮派至少有一人.该城有N个罪犯,编号从1至N(N<=100000.将有M(M<=100000)次操作.D a b 表示a.b是不同帮派A a b 询问a.b关系 Input 多组数据.第一行是数据总数 T (1 <= T <= 20)每组数据第一行是N.M,接下来M行是操作 Output 对于每一个A操作,回答"In the same gang.

(并查集)~APTX4869(fzu 2233)

http://acm.fzu.edu.cn/problem.php?pid=2233 Problem Description 为了帮助柯南回到一米七四,阿笠博士夜以继日地研究APTX4869的解药.他得出了如下结果: 1.解药由n种原料构成: 2.对于两种不同的的原料a,b,它们之间有个影响值f(a,b): 3.需要把原料分成两个部分X,Y,每部分中至少有一种原料: 4.解药的效果由分别属于X,Y的原料之间,最小的影响值决定,即 效果=min{f(a,b)|a∈X,b∈Y)} 博士需要你帮忙求出

【FZU】Problem 2059 MM(离线处理并查集)

离线处理,并查集 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100005; struct Node{ int id,value; }node[maxn],input[maxn]; bool cmp(Node p,Node q){ return p.value > q.value; } int p[maxn],vis[max

FZU 2112 并查集、欧拉通路

原题:http://acm.fzu.edu.cn/problem.php?pid=2112 首先是,票上没有提到的点是不需要去的. 然后我们先考虑这个图有几个联通分量,我们可以用一个并查集来维护,假设有n个联通分量,我们就需要n-1条边把他们连起来. 最后对于每个联通分量来说,我们要使它能一次走完,就是要求他是否满足欧拉通路,也就是这个联通分量中至多有2个度为奇数的点,每多出2个度为奇数的点,就多需要一条边(因为单个连通分量的所有点的度数之和为偶数,所以不可能存在奇数个奇数度数的点). 1 #i