C.Queue(模拟) C.Queue(模拟)

TimeLimit:2000MSMemoryLimit:262144KB Time\quad Limit:2000MS\quad Memory\quad Limit:262144KB
64bitIOFormat:%I64d|%I64u 64bit\quad IO\quad Format:\%I64d | \%I64u

Description Description

In the Main Berland Bank n n people stand in a queue at the cashier, everyone knows his/her height h i  h_i, and the heights of the other people in the queue. Each of them keeps in mind number a i  a_i — how many people who are taller than him/her and stand in queue in front of him.

After a while the cashier has a lunch break and the people in the queue seat on the chairs in the waiting room in a random order.

When the lunch break was over, it turned out that nobody can remember the exact order of the people in the queue, but everyone remembers his number a i  a_i.

Your task is to restore the order in which the people stood in the queue if it is possible. There may be several acceptable orders, but you need to find any of them. Also, you need to print a possible set of numbers h i  h_i — the heights of people in the queue, so that the numbers a i  a_i are correct.

Input Input

The first input line contains integer n n — the number of people in the queue (1 ≤ n ≤ 3000) (1 ≤ n ≤ 3000). Then n n lines contain descriptions of the people as “name i  name_i a i  a_i” (one description on one line), where name i  name_i is a non-empty string consisting of lowercase Latin letters whose length does not exceed 10 10 characters (the i-th person’s name), a i  a_i is an integer (0 ≤ ai ≤ n − 1) (0 ≤ ai ≤ n - 1), that represents the number of people who are higher and stand in the queue in front of person i i. It is guaranteed that all names are different.

Output Output

If there’s no acceptable order of the people in the queue, print the single line containing “−1 -1” without the quotes. Otherwise, print in n n lines the people as “name i  name_i h i  h_i”, where h i  h_i is the integer from 1 1 to 109 109 (inclusive), the possible height of a man whose name is name i  name_i. Print the people in the order in which they stand in the queue, starting from the head of the queue and moving to its tail. Numbers h i  h_i are not necessarily unique.


SampleInput Sample\quad Input
4
a 0
b 2
c 0
d 0
SampleOutput Sample\quad Output
a 150
c 170
d 180
b 160

SampleInput Sample\quad Input
4
vasya 0
petya 1
manya 3
dunay 3
SampleOutput Sample\quad Output
-1


题意

给定n n个人,并且给出某个人前方有多少个比他高的人的个数,求出他们的排列方式和每一个的高度,只要找出一种即可,如果找不出就输出−1 -1.

解题思路

方法1:

针对找不出一种的情况:

  1. 先对给定的n n个人进行排序,然后我们可以看出,如果当前某个人的前方人的个数r i  r_i比他自身所带的有多少个比他打的人的个数x i  x_i要小,则一定不满足条件,输出−1 -1.

针对能够找出的情况:

  1. 我们将对每一个人分配1−>n 1->n的高度,从个数x i  x_i高的开始处理,我们可以得知当前这个人能够得到的高度的最高值为n−x i  n-x_i,如果此数被占用了,就往下取就可以了,这样我们就能保证第i i位前面有且仅有x i  x_i个数比它大.

代码

时间复杂度:O(N⋅K) \color{red}{O(N\cdot K)}[ [ 其中K K的值被输入数据影响,但复杂度肯定比O(N 2 ) \color{red}{O(N^2)}小] ]

/*头文件模板*/#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>using namespace std;#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef pair<LL, LL>PLL;
typedef unsigned long long uLL;template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {int d = p < q ? 1 : -1;while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
}template<typename T>
void print (const T &a, string bes = "") {int len = bes.length();if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
}template<typename T>
void debug (T* p, T* q, string Gap = " ", bool flag = false) {
#ifndef ONLINE_JUDGEint d = p < q ? 1 : -1;cout << "Debug out : ";while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
#endif
}template<typename T>
void debug (const T &a, string bes = "") {
#ifndef ONLINE_JUDGEint len = bes.length();cout << "Debug out : ";if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
#endif
}void IO_Init() {ios::sync_with_stdio (false);
}LL LLabs (const LL a) {return a >= 0 ? a : -a;
}const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 3e3 + 5;
const int INF = 0x3f3f3f3f;/*头文件模板*/
struct o {string name;int h;o() {}o(string name, int h):name(name), h(h) {}bool operator < (const o & a) const {return h < a.h;}
};
o O[MAXN];
char S[MAXN];
bool visdp[MAXN];
int h[MAXN], n;
int main() {
#ifndef ONLINE_JUDGE//FIN;//FOUT;
#endifIO_Init();while(~scanf("%d", &n)) {int x;for(int i = 0; i < n; i ++) {scanf("%s%d", S, &x);O[i].name = string(S);O[i].h = x;}mem(visdp, false);sort(O, O + n);bool flag = true;for(int i = 0; i < n; i ++) {if(O[i].h > i) {flag = false;break;}}for(int i = n - 1; i >= 0; i --) {int k = n - O[i].h;while(visdp[k]) k --;visdp[h[i] = k] = true;}if(!flag) {puts("-1\n");continue;}for(int i = 0; i < n; i ++) {cout << O[i].name << ' ' << h[i] << endl;}}return 0;
}

方法2(codeforces (codeforces官方题解) ):
针对找不出一种的情况:

  1. 先对给定的n n个人进行排序,然后我们可以看出,如果当前某个人的前方人的个数r i  r_i比他自身所带的有多少个比他打的人的个数x i  x_i要小,则一定不满足条件,输出−1 -1.

    针对能够找出的情况:

    1. 循环遍历从0−>n 0->n,然后res.insert(res.begin() + O[i].h, o(O[i].name, O[i].h))即可.

    代码

    时间复杂度:O(N⋅K) \color{red}{O(N\cdot K)}[ [ 其中K K的值被输入数据影响,但复杂度肯定比O(N 2 ) \color{red}{O(N^2)}小] ]

    /*头文件模板*/#include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iomanip>
    #include <typeinfo>
    #include <iostream>
    #include <algorithm>
    #include <functional>using namespace std;#define pb push_back
    #define mp make_pair
    #define mem(a, x) memset(a, x, sizeof(a))
    #define copy(a, b) memcpy(a, b, sizeof(a))
    #define lson rt << 1, l, mid
    #define rson rt << 1|1, mid + 1, r
    #define FIN freopen("input.txt", "r", stdin)
    #define FOUT freopen("output.txt", "w", stdout)typedef long long LL;
    typedef pair<int, int > PII;
    typedef pair<int, string> PIS;
    typedef pair<LL, LL>PLL;
    typedef unsigned long long uLL;template<typename T>
    void print (T* p, T* q, string Gap = " ", bool flag = false) {int d = p < q ? 1 : -1;while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
    }template<typename T>
    void print (const T &a, string bes = "") {int len = bes.length();if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
    }template<typename T>
    void debug (T* p, T* q, string Gap = " ", bool flag = false) {
    #ifndef ONLINE_JUDGEint d = p < q ? 1 : -1;cout << "Debug out : ";while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
    #endif
    }template<typename T>
    void debug (const T &a, string bes = "") {
    #ifndef ONLINE_JUDGEint len = bes.length();cout << "Debug out : ";if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
    #endif
    }void IO_Init() {ios::sync_with_stdio (false);
    }LL LLabs (const LL a) {return a >= 0 ? a : -a;
    }const double PI = 3.1415926535898;
    const double eps = 1e-10;
    const int MAXM = 1e5 + 5;
    const int MAXN = 3e3 + 5;
    const int INF = 0x3f3f3f3f;/*头文件模板*/
    struct o {string name;int h;o() {}o(string name, int h):name(name), h(h) {}bool operator < (const o & a) const {return h < a.h;}
    };
    o O[MAXN];
    char S[MAXN];
    bool visdp[MAXN];
    int n;
    vector<o>res;
    int main() {
    #ifndef ONLINE_JUDGE//FIN;//FOUT;
    #endifIO_Init();while(~scanf("%d", &n)) {int x;for(int i = 0; i < n; i ++) {scanf("%s%d", S, &x);O[i].name = string(S);O[i].h = x;}res.clear();mem(visdp, false);sort(O, O + n);bool flag = true;for(int i = 0; i < n; i ++) {if(O[i].h > i) {flag = false;break;}}if(!flag) {puts("-1\n");continue;}for(int i = 0; i < n; i ++) {res.insert(res.begin() + O[i].h, o(O[i].name, n - i));}for(int i = 0; i < n; i ++) {cout << res[i].name << ' ' << res[i].h << endl;}}return 0;
    }
    

    D.Take−offRamps(最短路) D. Take-off Ramps(最短路)

    Vasya participates in a ski race along the X X axis. The start is at point 0 0, and the finish is at L L, that is, at a distance L L meters from the start in the positive direction of the axis. Vasya has been training so hard that he can run one meter in exactly one second.

    Besides, there are n n take-off ramps on the track, each ramp is characterized by four numbers:

    x i  x_i represents the ramp’s coordinate

    d i  d_i represents from how many meters Vasya will land if he goes down this ramp

    t i  t_i represents the flight time in seconds

    p i  p_i is the number, indicating for how many meters Vasya should gather speed to get ready and fly off the ramp. As Vasya gathers speed, he should ski on the snow (that is, he should not be flying), but his speed still equals one meter per second.

    Vasya is allowed to move in any direction on the X X axis, but he is prohibited to cross the start line, that is go to the negative semiaxis. Vasya himself chooses which take-off ramps he will use and in what order, that is, he is not obliged to take off from all the ramps he encounters. Specifically, Vasya can skip the ramp. It is guaranteed that x i  + d i  ≤ L x_i + d_i ≤ L, that is, Vasya cannot cross the finish line in flight.

    Vasya can jump from the ramp only in the positive direction of X X axis. More formally, when using the i i-th ramp, Vasya starts gathering speed at point x i  − p i  x_i - p_i, jumps at point x_i, and lands at point x i  + d i  x_i + d_i. He cannot use the ramp in opposite direction.

    Your task is to find the minimum time that Vasya will spend to cover the distance.

    Input

    The first line contains two integers n n and L(0 ≤ n ≤ 105,1 ≤ L ≤ 109) L (0 ≤ n ≤ 105, 1 ≤ L ≤ 109). Then n lines contain the descriptions of the ramps, each description is on a single line. Each description is a group of four non-negative integers x i ,d i ,t i ,p i (0 ≤ x i  ≤ L,1 ≤ d i , t i , p i  ≤ 109,x i  + d i  ≤ L) x_i, d_i, t_i, p_i (0 ≤ x_i ≤ L, 1 ≤ d_i, t_i, p_i ≤ 109, x_i + d_i ≤ L).

    Output

    Print in the first line the minimum time in seconds Vasya needs to complete the track. Print in the second line k k — the number of take-off ramps that Vasya needs to use, and print on the third line of output k k numbers the number the take-off ramps Vasya used in the order in which he used them. Print each number exactly once, separate the numbers with a space. The ramps are numbered starting from 1 1 in the order in which they are given in the input.

    Examples

    input input
    2 20
    5 10 5 5
    4 16 1 7
    output output
    15
    1
    1
    input input
    2 20
    9 8 12 6
    15 5 1 1
    output output
    16
    1
    2

    Note Note
    In the first sample, Vasya cannot use ramp 2 2, because then he will need to gather speed starting from point −3 -3, which is not permitted by the statement. The optimal option is using ramp 1 1, the resulting time is: moving to the point of gathering speed + + gathering speed until reaching the takeoff ramp + + flight time + moving to the finish line = 0 + 5 + 5 + 5 = 15 = 0 + 5 + 5 + 5 = 15.

    In the second sample using ramp 1 1 is not optimal for Vasya as t 1  > d 1  t_1 > d_1. The optimal option is using ramp 2 2, the resulting time is: moving to the point of gathering speed + + gathering speed until reaching the takeoff ramp + + flight time + + moving to the finish line = 14 + 1 + 1 + 0 = 16 = 14 + 1 + 1 + 0 = 16.

    题意

    有一个跑道,滑冰者从0 0开始滑冰到L L,中间给出了多个进行跳跃的部分,这些跳跃的部分有一定的缓冲区,从x i −p i  x_i-p_i开始缓冲,到达x i  x_i处跳跃至x i +d i  x_i + d_i,其中x i +d i  x_i+d_i这部分的时间花费为t i  t_i,而不是跳跃部分则1 1秒钟1 1米,最终求从0 0滑到L L最小花费多少时间?
    [ [记住一点,这个人可以往回走,这个点被坑了,实在是无法理解出题的人拿这个点坑人,竟然还可以直接往回走,我服了,如果第10 10组过不了,基本就是这个原因] ]

    解题思路

    将0,L,x i −p i ,x i +d i  0,L,x_i-p_i,x_i+d_i用Hash Hash将进行离散化,Hash Hash的方法有若干种,我直接用的map map,然后将这些点看成一个有向图上的点,其中花费t t则是点与点之间的有权值的边,如此便转换为求0 0到L L的最短路,时间复杂度基本就是求最短路的复杂度了.

    [ [这里我们可以记住一个技巧,单独求解一个点到另一个点的最小最大花费可以转换为图进行处理,我想很多图论方面都可以用来处理相应的问题] ]

    代码

    代码复杂度:O(E+VlogV) \color{red}{O(E+VlogV)}

    /*头文件模板*/#include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iomanip>
    #include <typeinfo>
    #include <iostream>
    #include <algorithm>
    #include <functional>using namespace std;#define pb push_back
    #define mp make_pair
    #define mem(a, x) memset(a, x, sizeof(a))
    #define copy(a, b) memcpy(a, b, sizeof(a))
    #define lson rt << 1, l, mid
    #define rson rt << 1|1, mid + 1, r
    #define FIN freopen("input.txt", "r", stdin)
    #define FOUT freopen("output.txt", "w", stdout)typedef long long LL;
    typedef pair<int, int > PII;
    typedef pair<int, string> PIS;
    typedef pair<LL, LL>PLL;
    typedef pair<LL, int>PLI;
    typedef unsigned long long uLL;template<typename T>
    void print (T* p, T* q, string Gap = " ", bool flag = false) {int d = p < q ? 1 : -1;while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
    }template<typename T>
    void print (const T &a, string bes = "") {int len = bes.length();if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
    }template<typename T>
    void debug (T* p, T* q, string Gap = " ", bool flag = false) {
    #ifndef ONLINE_JUDGEint d = p < q ? 1 : -1;cout << "Debug out : ";while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
    #endif
    }template<typename T>
    void debug (const T &a, string bes = "") {
    #ifndef ONLINE_JUDGEint len = bes.length();cout << "Debug out : ";if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
    #endif
    }void IO_Init() {ios::sync_with_stdio (false);
    }LL LLabs (const LL a) {return a >= 0 ? a : -a;
    }const double PI = 3.1415926535898;
    const double eps = 1e-10;
    const int MAXM = 1e5 + 5;
    const int MAXN = 2e5 + 5;
    const LL INF = 1e18;/*头文件模板*/struct o {LL x, d, t, p;
    } R[MAXN];
    struct Edge {int to, id;LL cost;bool operator < (const Edge & a) const {return cost < a.cost;}Edge() {}Edge(int to, LL cost, int id): to(to), cost(cost), id(id) {}
    };
    map<LL, int>DI;
    vector<Edge>G[MAXN];
    LL d[MAXN], L;
    int n;
    PII prev[MAXN];
    stack<int>S;
    void init() {DI.clear();for(int i = 0; i < MAXN; i ++) {G[i].clear();prev[i].first = i;prev[i].second = -1;}
    }void dijkstra() {priority_queue<PLI, vector<PLI>, greater<PLI> >que;fill(d, d + MAXN, INF);d[DI[0]] = 0;que.push(PII(0, 1));while(!que.empty()) {PLI p = que.top();que.pop();int v = p.second;if(d[v] < p.first) continue;for(int i = 0; i < G[v].size(); i ++) {Edge &e = G[v][i];if(d[e.to] > d[v] + e.cost) {d[e.to] = d[v] + e.cost;prev[e.to].first = v;prev[e.to].second = e.id;que.push(PII(d[e.to], e.to));}}}printf("%lld\n", d[DI[L]]);while(!S.empty()) S.pop();for(int t = DI[L]; t != prev[t].first; t = prev[t].first) {if(prev[t].second != -1) {S.push(prev[t].second);}}printf("%d\n", S.size());while(!S.empty()) {printf("%d", S.top());S.pop();if(S.empty()) {printf("\n");} else {printf(" ");}}
    }int main() {
    #ifndef ONLINE_JUDGE//FIN;//FOUT;
    #endifIO_Init();while(~scanf("%d%lld", &n, &L)) {init();DI[0] = 1;DI[L] = 1;for(int i = 0; i < n; i ++) {scanf("%lld%lld%lld%lld", &R[i].x, &R[i].d, &R[i].t, &R[i].p);if(R[i].x - R[i].p < 0 || R[i].x + R[i].d > L || R[i].t > R[i].p + R[i].d) continue;DI[R[i].x - R[i].p] = 1;DI[R[i].x + R[i].d] = 1;}int ib = 1;for(map<LL, int>::iterator it = DI.begin(), itt = DI.begin(); it != DI.end(); it ++) {if(ib > 1) {G[ib - 1].pb(Edge(ib, it -> first - itt -> first, -1));G[ib].pb(Edge(ib - 1, it -> first - itt -> first, -1));itt ++;}it -> second = ib ++;}for(int i = 0; i < n; i ++) {if(R[i].x - R[i].p < 0 || R[i].x + R[i].d > L || R[i].t > R[i].p + R[i].d) continue;int u = DI[R[i].x - R[i].p];int v = DI[R[i].x + R[i].d];G[u].pb(Edge(v, R[i].p + R[i].t, i + 1));}dijkstra();}return 0;
    }
    

    E.ClearingUp(并查集) E. Clearing\quad Up(并查集)

    TimeLimit:2000MSMemoryLimit:262144KB Time\quad Limit:2000MS\quad Memory\quad Limit:262144KB
    64bitIOFormat:%I64d|%I64u 64bit\quad IO\quad Format:\%I64d | \%I64u

    Description Description

    After Santa Claus and his assistant Elf delivered all the presents and made all the wishes come true, they returned to the North Pole and found out that it is all covered with snow. Both of them were quite tired and they decided only to remove the snow from the roads connecting huts. The North Pole has n huts connected with m roads. One can go along the roads in both directions.

    The Elf offered to split: Santa Claus will clear up the wide roads and the Elf will tread out the narrow roads. For each road they decided who will clear it: Santa Claus or the Elf. To minimize the efforts they decided to clear the road so as to fulfill both those conditions:

    between any two huts should exist exactly one simple path along the cleared roads;
    Santa Claus and the Elf should clear the same number of roads.
    At this point Santa Claus and his assistant Elf wondered which roads should they clear up?

    input input

    The first input line contains two positive integers n and m(1 ≤ n ≤ 103,1 ≤ m ≤ 105)  (1 ≤ n ≤ 103, 1 ≤ m ≤ 105) — the number of huts and the number of roads. Then follow m lines, each of them contains a road description: the numbers of huts it connects — x x and y y (1 ≤ x, y ≤ n) (1 ≤ x, y ≤ n) and the person responsible for clearing out this road ( (”S S” — for the Elf or “M M” for Santa Claus) ). It is possible to go on each road in both directions. Note that there can be more than one road between two huts and a road can begin and end in the same hut.

    Output Output

    Print “−1 -1” without the quotes if it is impossible to choose the roads that will be cleared by the given rule. Otherwise print in the first line how many roads should be cleared and in the second line print the numbers of those roads (the roads are numbered from 1 1 in the order of occurrence in the input). It is allowed to print the numbers of the roads in any order. Each number should be printed exactly once. As you print the numbers, separate them with spaces.


    SampleInput Sample\quad Input
    1 2
    1 1 S
    1 1 M
    SampleOutput Sample\quad Output
    0

    SampleInput Sample\quad Input
    3 3
    1 2 S
    1 3 M
    2 3 S
    SampleOutput Sample\quad Output
    2
    2 1
    SampleInput Sample\quad Input
    5 6
    1 1 S
    1 2 M
    1 3 S
    1 4 M
    1 5 M
    2 2 S

    SampleOutput Sample\quad Output
    -1


    题意

    有S S,M M两个不同颜色标记的边,求得一个生成树,其中两种颜色的边各占一半.

    解题思路

    1. 如果当前构成生成树的顶点为n n的话,如果n−1 n-1不是为偶数就输出−1 -1.

    2. 将当前的S S这个颜色构成的边全部都删除,即不加入生成树中,记剩下的联通块为cnt cnt,如果cnt−1>(n−1)2  cnt-1>{(n-1)\over 2},输出−1 -1,因为将所有的S S边都加上都无法满足两种颜色各占一半.

    3. 在2 2的基础上,我们将连接这些联通块的边保存起来,因为这些边必须要存在的,如果这些边不够(n−1)2  {(n-1)\over 2},则随意增加k k条边满足条件.

    4. 在3 3的基础上,将剩下的M M颜色的边加入,最后将生成树输出

    代码

    时间复杂度:O(N⋅E) \color{red}{O(N\cdot E)}

    /*头文件模板*/#include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iomanip>
    #include <typeinfo>
    #include <iostream>
    #include <algorithm>
    #include <functional>using namespace std;#define pb push_back
    #define mp make_pair
    #define mem(a, x) memset(a, x, sizeof(a))
    #define copy(a, b) memcpy(a, b, sizeof(a))
    #define lson rt << 1, l, mid
    #define rson rt << 1|1, mid + 1, r
    #define FIN freopen("input.txt", "r", stdin)
    #define FOUT freopen("output.txt", "w", stdout)typedef long long LL;
    typedef pair<int, int > PII;
    typedef pair<int, string> PIS;
    typedef pair<LL, LL>PLL;
    typedef unsigned long long uLL;template<typename T>
    void print (T* p, T* q, string Gap = " ", bool flag = false) {int d = p < q ? 1 : -1;while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
    }template<typename T>
    void print (const T &a, string bes = "") {int len = bes.length();if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
    }template<typename T>
    void debug (T* p, T* q, string Gap = " ", bool flag = false) {
    #ifndef ONLINE_JUDGEint d = p < q ? 1 : -1;cout << "Debug out : ";while (p != q) {if (flag) cout << Gap[0] << *p << Gap[1];else cout << *p;p += d;if (p != q && !flag) cout << Gap;}cout << endl;
    #endif
    }template<typename T>
    void debug (const T &a, string bes = "") {
    #ifndef ONLINE_JUDGEint len = bes.length();cout << "Debug out : ";if (len >= 2) cout << bes[0] << a << bes[1] << endl;else cout << a << endl;
    #endif
    }void IO_Init() {ios::sync_with_stdio (false);
    }LL LLabs (const LL a) {return a >= 0 ? a : -a;
    }const double PI = 3.1415926535898;
    const double eps = 1e-10;
    const int MAXM = 1e5 + 5;
    const int MAXN = 1e3 + 5;
    const int INF = 0x3f3f3f3f;/*头文件模板*/struct Edge {int x, y, b;Edge() {}Edge(int x, int y, int b = -1): x(x), y(y), b(b) {}
    };int n, m;
    int par[MAXN], ranks[MAXN];
    vector<Edge> S, W;//保存提供的边
    vector<PII> TS, TW;//保存最后会留在生成树中边
    void BC_init() {for(int i = 0; i < MAXN; i ++) {par[i] = i;ranks[i] = 0;}
    }int find(int x) {return par[x] == x ? x : par[x] = find(par[x]);
    }bool merge(int x, int y) {x = find(x);y = find(y);if(x == y) return false;if(ranks[x] < ranks[y]) {par[x] = y;} else {par[y] = x;if(ranks[x] == ranks[y]) {ranks[x] ++;}}return true;
    }int main() {
    #ifndef ONLINE_JUDGE//FIN;//FOUT;
    #endifIO_Init();while(~scanf("%d%d", &n, &m)) {int x, y;char who[2];S.clear(), W.clear();TS.clear(), TW.clear();for(int i = 0; i < m; i ++) {scanf("%d%d%s", &x, &y, who);if(who[0] == 'S') S.push_back(Edge(x, y, i + 1));else W.push_back(Edge(x, y, i + 1));}//顶点数目为偶数,提供的边的数目不满足条件if(n % 2 == 0 || n - 1 > m) {puts("-1");continue;}//初始化并查集BC_init();//求解多少个联通块int ltk = n;for(int i = 0; i < W.size(); i ++) {if(merge(W[i].x, W[i].y)) {ltk --;}}//如果不满足条件if(ltk - 1> (n - 1) >> 1) {puts("-1");continue;}//将连接这些联通块的边加入for(int i = 0; i <  S.size(); i ++) {if(merge(S[i].x, S[i].y)) {TS.push_back(PII(i, S[i].b));}}BC_init();//重构生成树,加入必须要加入的边for(int i = 0;i <  TS.size();i ++){merge(S[TS[i].first].x, S[TS[i].first].y);}//凑足(n-1)/2条边int sn = TS.size();for(int i = 0;i < S.size();i ++){if(sn == (n - 1) >> 1) break;if(merge(S[i].x, S[i].y)){sn ++;TS.push_back(PII(i, S[i].b));}}if(sn < (n - 1) >> 1){puts("-1");continue;}//凑足另外一条边int wn = 0;for(int i = 0;i < W.size();i ++){if(wn == (n - 1) >> 1) break;if(merge(W[i].x, W[i].y)){TW.push_back(PII(i, W[i].b));wn ++;}}if(wn < (n - 1) >> 1){puts("-1");break;}printf("%d\n", TW.size() + TS.size());for(int i = 0;i < TW.size();i ++){printf("%d", TW[i].second);if(i != TW.size() - 1) printf(" ");}for(int i = 0;i <  TS.size();i ++){printf(" %d", TS[i].second);}printf("\n");}return 0;
    }

Codeforces Round #101 (Div. 2)相关推荐

  1. Codeforces Round #723 (Div. 2)

    Codeforces Round #723 (Div. 2) 题号 题目 知识点 A Mean Inequality 签到 B I Hate 1111 思维 C Potions (Easy Versi ...

  2. Codeforces Round #735 (Div. 2)(A-D)没有B

    Codeforces Round #735 (Div. 2) A 一道小思维题 #include <bits/stdc++.h> using namespace std; #define ...

  3. Codeforces Round #257 (Div. 2)

    Codeforces Round #257 (Div. 2) https://codeforces.com/contest/450/ A 模拟 1 #include<bits/stdc++.h& ...

  4. Codeforces Round #597 (Div. 2) - BenFromHRBUST

    Codeforces Round #597 (Div. 2) -----比赛传送门----- A - Good ol' Numbers Coloring Problem Description Con ...

  5. Codeforces Round #723 Div. 2个人代码

    Codeforces Round #723 Div. 2个人代码 写出来四题,开心QWQ A. Mean Inequality 题意:给一个数n,然后给2*n个数,让我们构造一个数列满足数列中任意一项 ...

  6. Codeforces Round #670 (Div. 2)A-D题解

    Codeforces Round #670 (Div. 2)A-D题解 //写于rating值1987/2184 //补档 比赛链接:https://codeforces.ml/contest/140 ...

  7. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  8. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  9. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

最新文章

  1. [AlwaysOn Availability Groups]AlwaysOn健康诊断日志
  2. PyQt5 技术篇-QTableWidget表格组件的行选择与列选择实例演示,表格组件的双击事件捕获,获取表格选中单元格的值
  3. Python中列表和字符串的反转
  4. 「offer来了」2种递进学习思维,24道计网题目,保姆级巩固你的计网知识体系
  5. 200多个js技巧代码(五)
  6. Cisco3550三层交换机vlan间路由配置实例
  7. android版本更新代码
  8. 中秋逢国庆 | 盛世华诞 阖家团圆
  9. (一)音视频:解码H264文件流程 渲染和拿到解码后源数据YUV 完整Demo
  10. 从零玩转第三方登录之QQ登录
  11. Java毕业设计——员工管理系统
  12. python判断ip是否可以ping通
  13. 看板记录工具wekan
  14. 软件安装: 安装.deb文件操作
  15. TFT LCD液晶屏显示原理
  16. 1.Twitter开发者之如何申请一个twitter开发者账号
  17. 赛门铁克未署名诺顿安全更新 防火墙警报引混乱
  18. RK3399 HDCP 2.2key
  19. (8.1.5.4)Android Testing Support Library翻译之Espresso 备忘录
  20. java String.format()的问题

热门文章

  1. 这个Excel函数,推荐所有人学习!HR都说必须会
  2. 一对一直播,一对一脚本开发行业的下一个风口将在5G普及后到来!
  3. Cisco WLC 基础配置
  4. DEV gridview数据筛选
  5. M3U8 文件介绍 与 播放方法
  6. Android之Spinner使用详解
  7. [VB.NET]如何设置随机数的种子
  8. 2022年中国云计算面临的问题及发展前景预测分析
  9. linux 系统迁移 固态硬盘,系统迁移
  10. Lipschitz常数、Lipschitz条件