码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-25 22:31:21      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:acm   cf 队列   

题目链接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;
}


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

标签:acm   cf 队列   

原文地址:http://blog.csdn.net/u013050857/article/details/45974015

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!