HDU 5963 朋友/podruga (找规律+map&pair基本用法)

 Source:

http://acm.hdu.edu.cn/showproblem.php?pid=5963

题意:这是CCPC2016合肥站的C题,说有一棵树,每条边值为0 or 1,每次询问 指定一个点作为根,然后一群男孩女孩做游戏,轮流选点并翻转从这一点到根这条路径上的所有边的值,问谁最后获胜。

思路:典型的找规律,只需看根节点相连的边值为1的边有多少条即可,因为不论怎么翻每次翻转都会翻转一个连接着根节点的边值,而结束时连接根的边一定都是0,于是规律出来了:当连接根节点值为1的边数为偶数时Boys win!  反之Girls win!

剩下实现,用一个deg[]数组存储每个点相连边中边值为1的边的条数,但是这里邻接矩阵是有必要存下来的,因为后面涉及到要改边值的操作,必须要知道原来那条边的边值是多少,但是这里e[40005][40005]是开不下的,所以要么只存n-1条边然后二分查找,要么就用STL的map来维护数据。

这里采用map实现,这里是map的用法详解map用法详解

STL的map常用用法如下:

头文件:#include<map>  //注意,STL头文件没有扩展名.h

声明:Map<int, string> mapStudent;  

      (也可以声明成本题需要的  map<pair<int,int>,int> amap )

基本操作:

  • mapStudent.clear() 移除容器中所有数据 注意:用于初始化,一定不能忘记清零操作
  • mapStudent.empty()  mapStudent为空时返回true
  • mapstudent[1]="Marta" 在mapstudent中插入元素(直接当做数组用很方便!)
  • 迭代器相关用法有待填坑

STL的pair常用用法如下

头文件:#include<utility>  //注意,STL头文件没有扩展名.h

声明:pair<int, double> p1;

基本操作:

  • p1=make_pair(1,1.2)    make_pair函数,其实就是一个结构体


PS:这里有必要介绍一个万能头文件:#include<bits/stdc++.h>

      包含了目前所有头文件(有点开挂,就是不知道评测器支不支持)


下面代码:

#include <stdio.h>
#include <string.h>
#include<map>
#include<utility>
using namespace std;
int deg[40005];
map<pair<int,int>,int> amap;

int main()
{
    int t,n,m,x,y,z,id,j;
    scanf("%d",&t);
    while(t--)
    {
        memset(deg,0,sizeof(deg));
        amap.clear();
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(x>y){int te=x;x=y;y=te;}  //统一顺序这样方便后期查找
            amap[make_pair(x,y)]=z;
            if(z==1)
            {
                deg[x]++;
                deg[y]++;
            }
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&id);
            if(id==0)
            {
                scanf("%d",&x);
                if(deg[x]%2) printf("Girls win!\n");
                else printf("Boys win!\n");
            }
            else
            {
                scanf("%d%d%d",&x,&y,&z);
                if(x>y){int te=x;x=y;y=te;}
                if(amap[make_pair(x,y)]!=z)
                    if(z==0)
                    {
                        amap[make_pair(x,y)]=0;
                        deg[x]--;
                        deg[y]--;
                    }
                    else
                    {
                        amap[make_pair(x,y)]=1;
                        deg[x]++;
                        deg[y]++;
                    }
            }
        }
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值