Codeforces Round #149 (Div. 2) Dispute (队列+容器模拟)

题目链接click here~~

【题目大意】

给定一个无向图,图中的每个结点最初的权值都为0。但每个结点有一次机会,可以增加它本身的权值,但是有个副作用即:在增加自己权值的情况下,也会增加与自己直接相连的结点的权值。 Ignat和Valera打赌说:valera不可能找到一种方法,使得对于每个结点i,它的权值不等于lgnat给定的ai。然后,题目要求写个程序,让valera可以胜,并输出哪个结点要用到,它给定的那次增加的机会。

输入:第1行n,m(1<=n,m<=10^5)分别表示有n个结点,和m条边

第2行到第m+1行每行有两个数u,v,表示结点u,v间有一条边

第m+2行,有n个数表示Ignat 给的ai

输出:若Ignal可以胜,就输出那个有用掉那个机会的结点,否则输出-1

【解题思路】:

CF的题还是比较考思维性的,以后要多刷刷。。

开始还以为是道图论的题,好久没写图论的题了,建边都不会了,后来想了想,可以用队列+容器来写,其实可以发现如果(all)num[i]!=0,即每个counter的权值都不为0 的话,那么之后的操作肯定会改变之后要操作的counter的权值,这种情况是valera的必胜局,那么另一种情况,只要发现num[i]!=0的话,就把它加入队列,输出队列的头部,并且减少与该点相连的所有其他点的权值,与队首相连的元素(比如j)
的权值减1。若它的值为0,则入队。循环操作直到队空。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int INF=0x3f3f3f3f;
vector<int > Edge[N];
vector<int > G;
queue<int>vec;
int num[N];
int main()
{
    int n,m,u,v,cost;
    scanf("%d%d",&n,&m);
    for(int i=0; i<m; i++){
        scanf("%d%d",&u,&v);
        Edge[u].push_back(v);
        Edge[v].push_back(u);
    }
    for(int i=1; i<=n; i++){
        scanf("%d",&num[i]);
        if(num[i]==0)
            vec.push(i);
    }
    while(!vec.empty())
    {
        int head=vec.front();
        vec.pop();
        G.push_back(head);
        for(int i=0; i<Edge[head].size(); i++){
            int next=Edge[head][i];
            num[next]--;
            if(num[next]==0)
                vec.push(next);
        }
    }
    printf("%d\n",G.size());
    for(int i=0; i<G.size(); i++){
        if(G.size()-1==i)
            printf("%d\n",G[i]);
        else
            printf("%d ",G[i]);
    }
    return 0;
}
时间: 2024-10-14 06:38:02

Codeforces Round #149 (Div. 2) Dispute (队列+容器模拟)的相关文章

Codeforces Round #149 (Div. 2)

这个round真的太简单了.. A,B就不说了 C  题目说了合法的点不会超过10^5个 那么直接离散化,完了跑bfs就行了 离散化用map就行 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <ctime> #include <set> #include &l

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题是线段树成段更新,但是不能直接更新,不然只能一个数一个数更新.这样只能把每个数存到一个数组中,长度大概是20吧,然后模拟二进制的位操作.仔细一点就行了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath>

Codeforces Round #316 (Div. 2)C. Replacement(模拟)

传送门 Description Daniel has a string s, consisting of lowercase English letters and period signs (characters '.'). Let's define the operation of replacement as the following sequence of steps: find a substring ".." (two consecutive periods) in st

Codeforces Round #315 (Div. 2) 569A Music (模拟)

题目:Click here 题意:(据说这个题的题意坑了不少人啊~~~)题目一共给了3个数---- T 表示歌曲的长度(s).S 表示下载了歌曲的S后开始第一次播放(也就是说S秒的歌曲是事先下载好的).q 表示下载速度(每秒下载歌曲(q-1)/q秒).问题就是播放的速度比下载的速度慢,每当播放到没下载的位置,就会重新从头播放,输出的就是从头播放的次数(包括第一次). 分析:高中物理追击问题,模拟下好了. 1 #include <bits/stdc++.h> 2 using namespace

Codeforces Round #601 (Div. 2)D(蛇形模拟)

1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 vector<char>ans; 5 char a[107][107]; 6 int main(){ 7 ios::sync_with_stdio(false); 8 cin.tie(NULL); 9 cout.tie(NULL); 10 for(int i='0';i<='9';++i) 11 ans.empla

Codeforces Round #354 (Div. 2) ABCD

Codeforces Round #354 (Div. 2) Problems # Name     A Nicholas and Permutation standard input/output 1 s, 256 MB    x3384 B Pyramid of Glasses standard input/output 1 s, 256 MB    x1462 C Vasya and String standard input/output 1 s, 256 MB    x1393 D T

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #257 (Div. 2) A/B/C/D

前三题早就写好了,一直在纠结D A. Jzzhu and Children 题意:就是简单的模拟,给排成一队的孩子分发糖果,每个孩子有至少要得到的糖果数. 然后每次给队头的孩子分发m个糖果,如果他已经得到了足够的糖果(大于等于他想得到的 最少糖果数)那么他就出队,否则他就去队尾.问最后一个孩子的编号. 算法:队列模拟,水题~ #include<cstdio> #include<iostream> #include<cstring> #include<queue&g