1013 Image Segmentation
Statement
Metadata
- 作者: ZHU, Jianke
- 单位: 浙江大学
- 代码长度限制: 16 KB
- 时间限制: 200 ms
- 内存限制: 64 MB
Image segmentation is usually formulated as a graph partition problem, where each segment corresponds to a connected component. Moreover, each pixel is the vertex of the graph. Each edge has a weight, which is a non-negative dissimilarity between neighboring pixels. So, the goal of image segmentation is to decompose the image graph into several disconnected components, where the elements in a component are similar and the elements in the different components are dissimilar.
The components are defined as follows:
- A component is made of a set of connected vertices;
- Any two components have no shared vertices;
- The dissimilarity
of any two components and is larger than the confidence of any of and . - The dissimilarity
is defined to be the minimum edge weight of all the edges connecting and , or infinity if no such edge exists; - The confidence of a component
, , is defined to be the maximum edge weight of the minimum spanning tree of , plus a function where is a positive constant and is the size of the component ; - A set of vertices must not be treated as a component if they can be partitioned into two or more components.
Your job is to write a program to list all the components.
Input Specification
Each input file contains one test case. For each case, the first line contains three integers:
Note: it is guaranteed that each pixel has no more than 8 neighboring pixels. The constant and all the weights are positive and are no more than 1000.
Output Specification
For each case, list each component in a line. The vertices in a component must be printed in increasing order, separated by one space with no extra space at the beginning or the end of the line. The components must be listed in increasing order of their first vertex.
Sample Input 1
10 21 100
0 1 10
0 3 60
0 4 90
1 2 90
1 3 50
1 4 200
1 5 86
2 4 95
2 5 5
3 4 95
3 6 15
3 7 101
4 5 500
4 6 100
4 7 101
4 8 101
5 7 300
5 8 50
6 7 90
7 8 84
7 9 34
Sample Output 1
Sample Input 2
Sample Output 2
Solution
#include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int(x.size()))
const int N = 1e3 + 10;
int n, m, c;
struct E {
int u, v, w;
bool operator<(const E &other) const {
return w < other.w;
}
} e[N * N];
inline int ceil(int x, int y) {
if (x % y == 0)
return x / y + 1;
return (x + y - 1) / y;
}
struct UFS {
int fa[N], sze[N], Max[N], MinID[N];
void init(int n) {
for (int i = 1; i <= n; ++i) {
fa[i] = 0;
sze[i] = 1;
Max[i] = 0;
MinID[i] = i;
}
}
int find(int x) {
return fa[x] == 0 ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y, int _Max) {
x = find(x), y = find(y);
if (x != y) {
fa[x] = y;
sze[y] += sze[x];
Max[y] = _Max;
MinID[y] = min(MinID[y], MinID[x]);
}
}
bool same(int u, int v) {
return find(u) == find(v);
}
int H(int u) {
u = find(u);
return Max[u] + c / sze[u];
// ceil(c, sze[u]);
}
} ufs;
void gao() {
sort(e + 1, e + 1 + m);
ufs.init(n);
for (int i = 1; i <= m; ++i) {
int u = e[i].u, v = e[i].v, w = e[i].w;
if (ufs.same(u, v))
continue;
if (w <= ufs.H(u) && w <= ufs.H(v)) {
ufs.merge(u, v, w);
}
}
vector<vector<int>> vec(n + 5);
for (int i = 1; i <= n; ++i) {
vec[ufs.MinID[ufs.find(i)]].push_back(i);
}
for (auto &it : vec)
if (!it.empty()) {
sort(it.begin(), it.end());
for (int i = 0; i < SZ(it); ++i) printf("%d%c", it[i] - 1, " \n"[i == SZ(it) - 1]);
}
}
int main() {
scanf("%d%d%d", &n, &m, &c);
for (int i = 1; i <= m; ++i) {
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
++e[i].u, ++e[i].v;
}
gao();
return 0;
}