zoukankan      html  css  js  c++  java
  • CF1423N BubbleSquare Tokens

    I.CF1423N BubbleSquare Tokens

    神仙构造题。

    首先,我们令所有点初始都没有放币,所有边上都放了一个币。则此时每个点的权值即为它的度数。

    然后,我们考虑从小到大计算每个点的权值。对于每个点(i),我们枚举它所有相邻且编号比它小的点,假如该点上没有币,就把币从连接两点的边上移到另一端的点上。明显这样操作并不会改变该点的权值,只会减少当前点的权值。

    这之后,上述所有点上都有了币。则我们可以选择将某些币移回边上,显然这只会单纯增加当前点的权值。假设当前点与(k)个点相邻,则它的权值可以被加上([0,k])中任何一个数(取决于你究竟打算移回多少个币)。而这共(k+1)个值中,最多只有(k)个值被其余点占去,则当前点完全可以占住剩下那一个。直接使用一个哈希表维护有哪些值被占去即可。

    时间复杂度(O(klog n))(O(k)),取决于使用哪种哈希表。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,cnt;
    bool on[12510];
    int sum[12510];
    int val[1001000],s[1001000],t[1001000];
    vector<int>v[12510];
    set<int>hs;
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)scanf("%d%d",&s[i],&t[i]),val[i]=1,sum[s[i]]++,sum[t[i]]++,v[s[i]].push_back(i),v[t[i]].push_back(i);
    	for(int i=1;i<=n;i++){
    		for(auto j:v[i]){
    			if((s[j]^t[j]^i)>i)continue;
    			if(!on[s[j]^t[j]^i])on[s[j]^t[j]^i]=true,val[j]--,sum[i]--;
    			hs.insert(sum[s[j]^t[j]^i]); 
    		}
    		for(auto j:v[i]){
    			if((s[j]^t[j]^i)>i)continue;
    			if(hs.find(sum[i])==hs.end())break;
    			on[s[j]^t[j]^i]=false,val[j]++,sum[i]++;
    		}
    		hs.clear();
    	}
    	for(int i=1;i<=n;i++)cnt+=on[i];
    	printf("%d
    ",cnt);
    	for(int i=1;i<=n;i++)if(on[i])printf("%d ",i);if(cnt)puts("");
    	for(int i=1;i<=m;i++)printf("%d %d %d
    ",s[i],t[i],val[i]);
    	return 0;
    }
    

  • 相关阅读:
    python模块添加
    Python 的列表排序
    python中文处理问题
    排序算法堆排序
    搜索二分搜索
    排序算法(随机)快速排序(递归)
    排序算法计数排序
    OO设计原则总结
    异常控制以及进程调度
    ubuntu12.04 alternate win7 双系统安装
  • 原文地址:https://www.cnblogs.com/Troverld/p/14621729.html
Copyright © 2011-2022 走看看