hihoCoder 1161 八卦的小冰 编程之美2015初赛第二场

我有一种自己水掉了这一题的嫌疑><待会研究一下官方题解。

比赛的时候脑抽写了个bfs暴力,WA到最后才想起来图可能是不联通的。

在这里直接预处理计算亲密度,按照无向图计算最后结果除以二即可,修改时只要修改变化的点对总亲密度的影响。

我觉得这么做最坏情况也是O(N^2)吧,比如一个节点连着十万个节点,每次询问都是修改这个节点的sex,plus询问十万次,但不造为啥还是没有T。o(╯□╰)o

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<ctype.h>
#include<map>
#include<time.h>
#include<bitset>
#include<set>
#include<list>
using namespace std;
//hiho 1161

const int maxn=100010;
int T;
int N;
int M;
int Q;
int x;
int y;
int z;
int sex[maxn];
class node
{
public:
    int idx;
    int wei;
public:
    node()
    {
        idx=0;
        wei=0;
    }
    node(int id,int we)
    {
        idx=id;
        wei=we;
    }
    void cle()
    {
        idx=0;
        wei=0;
    }
};
vector<node>mp[maxn];
long long ans;
void getnum()
{
    ans=0;
    for(int i=1;i<=N;i++)
    {
        for(int j=0;j<mp[i].size();j++)
        {
            int next=mp[i][j].idx;
            //cout<<i<<" "<<next<<endl;
            if(sex[i]!=sex[next])
            {
                ans+=mp[i][j].wei;
            }
        }
    }
    ans/=2;
}
int main()
{
    freopen("input.txt","r",stdin);
    //freopen("out2.txt","w",stdout);
    scanf("%d",&T);
    for(int ca=1;ca<=T;ca++)
    {
        scanf("%d %d %d",&N,&M,&Q);
        memset(sex,0,sizeof(sex));
        ans=0;
        for(int i=0;i<=N;i++)
        {
            mp[i].clear();
            for(int j=0;j<mp[i].size();j++)
            {
                mp[i][j].cle();
            }
        }
        for(int i=1;i<=N;i++)
        {
            int gen;
            scanf("%d",&gen);
            sex[i]=gen;
        }
        for(int i=1;i<=M;i++)
        {
            scanf("%d %d %d",&x,&y,&z);
            node tmp=node(y,z);
            mp[x].push_back(tmp);
            tmp=node(x,z);
            mp[y].push_back(tmp);
//            if(sex[x]!=sex[y]) it's also fine
//            {
//                ans+=z;
//            }
        }
        getnum();
        printf("Case #%d:\n",ca);
        for(int i=1;i<=Q;i++)
        {
            int op;
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d",&x);
                sex[x]=1-sex[x];
                for(int j=0;j<mp[x].size();j++)
                {
                    int next=mp[x][j].idx;
                    if(sex[x]==sex[next])
                    {
                        ans-=mp[x][j].wei;
                    }
                    else
                    {
                        ans+=mp[x][j].wei;
                    }
                }
            }
            else if(op==2)
            {
                bool flg=false;
                scanf("%d %d %d",&x,&y,&z);
                for(int j=0;j<mp[x].size();j++)
                {
                    if(mp[x][j].idx==y)
                    {
                        int pre=mp[x][j].wei;
                        mp[x][j].wei=z;
                        flg=true;
                        if(sex[x]!=sex[y])
                        {
                            ans+=(z-pre);
                        }
                        break;
                    }
                }
                for(int j=0;j<mp[y].size();j++)
                {
                    if(mp[y][j].idx==x)
                    {
                        flg=true;
                        mp[y][j].wei=z;
                        break;
                    }
                }
                if(flg==false)// if not exist
                {
                    node tmp=node(y,z);
                    mp[x].push_back(tmp);
                    tmp=node(x,z);
                    mp[y].push_back(tmp);
                    if(sex[x]!=sex[y])
                    {
                        ans+=z;
                    }
                }
            }
            else if(op==3)
            {
                printf("%lld\n",ans);//之前RE是因为这里写成了I64d ><
            }
        }
    }
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值