2020.09.27--2019年ACM省赛补题

D-Game on a Graph

There are  K people playing a game on a connected undirected simple graph with  n(n>=2) vertices (numbered from 0 to (n-1)) and  edges. These people, numbered from 0 to(k-1) , are divided into two groups and the game goes as follows:

  • They take turns to make the move. That is to say, person number 0 will make the 1st move, person number 1 will make the 2nd move, ..., person number(i mod k)  will make the (i+1)-th move.
  • During a move, the current player MUST select an edge from the current graph and remove it. If the graph is no longer connected after removing the edge, the group this person belongs to loses the game (and of course their opponents win), and the game ends immediately.

 Given the initial graph when the game starts, if all people use the best strategy to win the game for their groups, which group will win the game?

Recall that a simple graph is a graph with no self loops or multiple edges.

Input

There are multiple test cases. The first line of the input contains an integer T , indicating the number of test cases. For each test case:

The first line contains an integer  k (2<=k<=10^5), indicating the number of people.

The second line contains a string s0 s1...sk-1 of length k

indicates that person number  belongs to the 1st group, and si='2' indicates that person number  belongs to the 2nd group.

The third line contains two integers  n and m (2<=n<=10^5,n-1<=m<=10^5 ), indicating the number of vertices and edges of the initial graph.

The following  lines each contains two integers ui  and vi (0<=ui,vi<=n), indicating that there is an edge connecting vertex  and  in the initial graph.

It's guaranteed that:

  • The initial graph is a connected undirected simple graph.
  • There exist two people who belong to different groups.
  • The sum of k , the sum of  and the sum of  in all test cases will not exceed 10^6.

 

Output

For each test case output one line containing one integer. If the 1st group wins, output "1" (without quotes); If the 2nd group wins, output "2" (without quotes).

Sample Input

3
5
11212
4 6
0 1
0 2
0 3
1 2
1 3
2 3
5
11121
5 7
0 2
1 3
2 4
0 3
1 2
3 2
4 1
3
121
4 3
0 1
0 2
1 3

Sample Output

2
1
2

题意:n个点,联通这些点有有限个边,每次移走一条边,当这些点不在联通,判定为输掉。
思路:对于n个点,联通最起码需要n-1条边,所以当m条边移走到n-2条时判定为输。
#include<bits/stdc++.h>
using namespace std;
long long t,k,n,m,i,j,u,v;
const int N=1e6+10;
char s[N];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>k;
        cin>>s;
        cin>>n>>m;
        
        for(i=0;i<m;i++)
        {
            cin>>u>>v;
        }
        
            if(m-n+1>0)    //判断开始是否连通
            {
                if(s[(m-n+1)%k]=='1')  //从m到n-1需要多少步
                     cout<<"2"<<endl;
                
                else cout<<"1"<<endl;
            }
            else    //如果开始就不满足连通直接判断第一个队伍          {
                if(s[0]=='1')
                cout<<"2"<<endl;
                else cout<<"1"<<endl;
            }
    }
}

 

H-Tokens on the Segments

Consider n segments on a two-dimensional plane, where the endpoints of the i-th segment are (l(i),i) and (r(i),i). One can put as many tokens as he likes on the integer points of the plane (recall that an integer point is a point whose x and y coordinates are both integers), but the x coordinates of the tokens must be different from each other.

What’s the maximum possible number of segments that have at least one token on each of them?

Input
The first line of the input contains an integer T (about 100), indicating the number of test cases. For each test case:

The first line contains one integer n (1<=n<=1e5), indicating the number of segments.

For the next lines, the -th line contains 2 integers l(i),r(i) (1<=l(i)<=r(i)<=1e9), indicating the coordinates of the two endpoints of the -th segment.

It’s guaranteed that at most 5 test cases have n>=100.

Output
For each test case output one line containing one integer, indicating the maximum possible number of segments that have at least one token on each of them.

Sample Input
2
3
1 2
1 1
2 3
3
1 2
1 1
2 2
Sample Output
3
2
Hint
For the first sample test case, one can put three tokens separately on (1, 2), (2, 1) and (3, 3).

For the second sample test case, one can put two tokens separately on (1, 2) and (2, 3).

题意:在二维坐标系中,本题给出若干个线段的头坐标,尾坐标(可能重合),我们需要在线段整点处放置令牌,

        并且每条线段仅能放一块令牌,每块令牌的横坐标不能重合,问最多有几条线段能被放置令牌。

思路:此题需要用到优先数列,找到相同头坐标的线段选择最短的那条。依次排查计数。

因为优先数列这部分之前没了解过所以在网上找到一份代码。尽可能去理解。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=100010;
struct node          //将线段定义为一个机构体,内含头坐标尾坐标
{
    int st,en;
}s;
bool operator <(node a,node b)   //重载小于号
{
    if(a.st!=b.st)
        return a.st>b.st;
    return a.en>b.en;
}
priority_queue<node>q;     //优先数列
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,se,en;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&s.st,&s.en);
            q.push(s);
        }
        int mmax=0;
        int ans=0;
        while(!q.empty())
        {
            node now=q.top();
            q.pop();
            if(now.st<=mmax&&now.st+1<=now.en)   //头尾比较是否可以放置
            {
                now.st++;
                q.push(now);
            }
            else if(now.st>mmax)
            {
                ans ++;
                mmax=now.st;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2020-10-04 10:57  xiaoxu778  阅读(308)  评论(0)    收藏  举报