답안 #397848

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
397848 2021-05-03T09:35:46 Z maomao90 Roadside Advertisements (NOI17_roadsideadverts) C++14
100 / 100
945 ms 11596 KB
#include <cstdio>
#include <vector>
#include <cstring>
#include <utility>
#include <algorithm>
#include <set>
#include <tuple>

#pragma(once)

using namespace std;

typedef pair <int, int> ii;
typedef tuple <int, int, int> iii;

#define INF 1000000005

//#define DEBUG

class UnionFind
{
private:
    vector <int> p, ranks;
public:
    void initialise(int n)
    {
        p.assign(n, 0); ranks.assign(n, 1);
        for (int i = 0; i < n; i++) p[i] = i;
    }
    int findSet(int a)
    {
        if (p[a] == a) return a;
        return p[a] = findSet(p[a]);
    }
    bool isSameSet(int a, int b)
    {
        return findSet(a) == findSet(b);
    }
    void unionSet(int a, int b)
    {
        if (!isSameSet(a, b))
        {
            int pa = findSet(a), pb = findSet(b);
            if (ranks[pa] < ranks[pb]) p[pa] = pb;
            else
            {
                p[pb] = pa;
                if (ranks[pa] == ranks[pb])
                {
                    ranks[pa]++;
                }
            }
        }
    }
};

int V, Q;
vector <ii> adjList[50005];
int sponsors[5];
bool isSponsor[50005];
int level[50005];
int dist[50005];
int p[20][50005];

int adjMatrix[50][50];
vector <iii> edgeList;
set <int> processing;
vector <int> vertices;
UnionFind UF;
int ans;

int LCA(int a, int b)
{
	if (level[a] < level[b]) swap(a, b);
	for (int i = 19; i >= 0; i--)
	{
		if (level[p[i][a]] >= level[b] && p[i][a] != -1)
		{
			a = p[i][a];
		}
	}

	if (a == b) return a;

	for (int i = 19; i >= 0; i--)
	{
		if (p[i][a] != p[i][b])
		{
			a = p[i][a]; b = p[i][b];
		}
	}
	return p[0][a];
}

void root(int source, int prevDist, int prevLvl, int prevP)
{
	dist[source] = prevDist;
	p[0][source] = prevP;
	level[source] = prevLvl;
	for (ii neighbour : adjList[source])
	{
		if (neighbour.first != prevP)
		{
			root(neighbour.first, prevDist + neighbour.second, prevLvl + 1, source);
		}
	}
}

int main()
{
	scanf("%d", &V);
	for (int i = 0; i < V-1; i++)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		adjList[u].emplace_back(v, w);
		adjList[v].emplace_back(u, w);
	}
	memset(p, -1, sizeof(p));
	root(0, 0, 0, -1);

	for (int k = 1; k < 20; k++)
	{
		for (int i = 0; i < V; i++)
		{
			if (p[k-1][i] != -1)
			{
				p[k][i] = p[k-1][p[k-1][i]];
			}
			else p[k][i] = -1;
		}
	}

	scanf("%d", &Q);
	for (int i = 0; i < Q; i++)
	{
		memset(isSponsor, false, sizeof(isSponsor));
		for (int j = 0; j < 5; j++)
		{
			scanf("%d", sponsors + j);
			isSponsor[sponsors[j]] = true;
		}

		edgeList.clear();
		processing.clear();
		vertices.clear();
		for (int j = 0; j < 5; j++)
		{
			int cnt = 0;
			for (int k = j + 1; k < 5; k++)
			{
			    int temp = LCA(sponsors[j], sponsors[k]);
				processing.insert(temp);
			}
			processing.insert(sponsors[j]);
		}

		for (auto &i : processing) vertices.push_back(i);
		for (int j = 0; j < vertices.size(); j++) {
			for (int k = j + 1; k < vertices.size(); k++) {
				int tempj = vertices[j], tempk = vertices[k];
				int lca = LCA(tempj, tempk);
				edgeList.emplace_back(dist[tempj] + dist[tempk] - 2 * dist[lca], tempj, tempk);
			}
		}
		sort(edgeList.begin(), edgeList.end());

		ans = 0;
		UF.initialise(V+5);
		for (int j = 0; j < edgeList.size(); j++)
		{
		    int u, v, w; tie(w, u, v) = edgeList[j];
		    if (!UF.isSameSet(u, v))
            {
                ans += w;
                UF.unionSet(u, v);
            }
		}
		printf("%d\n", ans);
	}
	return 0;
}

/*
6
4 0 4
0 1 2
1 3 9
3 5 1
3 2 5
2
4 0 3 5 2
0 4 1 3 5
*/

Compilation message

roadsideadverts.cpp:9: warning: ignoring #pragma ( once [-Wunknown-pragmas]
    9 | #pragma(once)
      | 
roadsideadverts.cpp: In function 'int main()':
roadsideadverts.cpp:149:8: warning: unused variable 'cnt' [-Wunused-variable]
  149 |    int cnt = 0;
      |        ^~~
roadsideadverts.cpp:159:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  159 |   for (int j = 0; j < vertices.size(); j++) {
      |                   ~~^~~~~~~~~~~~~~~~~
roadsideadverts.cpp:160:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  160 |    for (int k = j + 1; k < vertices.size(); k++) {
      |                        ~~^~~~~~~~~~~~~~~~~
roadsideadverts.cpp:170:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::tuple<int, int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  170 |   for (int j = 0; j < edgeList.size(); j++)
      |                   ~~^~~~~~~~~~~~~~~~~
roadsideadverts.cpp:111:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  111 |  scanf("%d", &V);
      |  ~~~~~^~~~~~~~~~
roadsideadverts.cpp:115:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  115 |   scanf("%d%d%d", &u, &v, &w);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
roadsideadverts.cpp:134:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  134 |  scanf("%d", &Q);
      |  ~~~~~^~~~~~~~~~
roadsideadverts.cpp:140:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  140 |    scanf("%d", sponsors + j);
      |    ~~~~~^~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5324 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 913 ms 9428 KB Output is correct
2 Correct 886 ms 10948 KB Output is correct
3 Correct 881 ms 11192 KB Output is correct
4 Correct 879 ms 11080 KB Output is correct
5 Correct 882 ms 10952 KB Output is correct
6 Correct 912 ms 10948 KB Output is correct
7 Correct 880 ms 11024 KB Output is correct
8 Correct 870 ms 11052 KB Output is correct
9 Correct 873 ms 11036 KB Output is correct
10 Correct 890 ms 10964 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 38 ms 8004 KB Output is correct
2 Correct 41 ms 10312 KB Output is correct
3 Correct 45 ms 10444 KB Output is correct
4 Correct 40 ms 10368 KB Output is correct
5 Correct 44 ms 10328 KB Output is correct
6 Correct 45 ms 10332 KB Output is correct
7 Correct 42 ms 10360 KB Output is correct
8 Correct 44 ms 10356 KB Output is correct
9 Correct 42 ms 10444 KB Output is correct
10 Correct 44 ms 10400 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5324 KB Output is correct
2 Correct 913 ms 9428 KB Output is correct
3 Correct 886 ms 10948 KB Output is correct
4 Correct 881 ms 11192 KB Output is correct
5 Correct 879 ms 11080 KB Output is correct
6 Correct 882 ms 10952 KB Output is correct
7 Correct 912 ms 10948 KB Output is correct
8 Correct 880 ms 11024 KB Output is correct
9 Correct 870 ms 11052 KB Output is correct
10 Correct 873 ms 11036 KB Output is correct
11 Correct 890 ms 10964 KB Output is correct
12 Correct 38 ms 8004 KB Output is correct
13 Correct 41 ms 10312 KB Output is correct
14 Correct 45 ms 10444 KB Output is correct
15 Correct 40 ms 10368 KB Output is correct
16 Correct 44 ms 10328 KB Output is correct
17 Correct 45 ms 10332 KB Output is correct
18 Correct 42 ms 10360 KB Output is correct
19 Correct 44 ms 10356 KB Output is correct
20 Correct 42 ms 10444 KB Output is correct
21 Correct 44 ms 10400 KB Output is correct
22 Correct 927 ms 9512 KB Output is correct
23 Correct 879 ms 8132 KB Output is correct
24 Correct 917 ms 10792 KB Output is correct
25 Correct 945 ms 11572 KB Output is correct
26 Correct 935 ms 11596 KB Output is correct
27 Correct 929 ms 11460 KB Output is correct
28 Correct 927 ms 11592 KB Output is correct
29 Correct 912 ms 11552 KB Output is correct
30 Correct 902 ms 11584 KB Output is correct
31 Correct 918 ms 11540 KB Output is correct