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;
    }
    

  • 相关阅读:
    极客教学笔记---Java实现简单聊天客户端模拟
    java单例模式四模板
    关于在命令行进行文件输入输出重定向的小笔记
    Python爬虫入门之爬取图片
    Python爬虫入门之查询ip地址
    Python爬虫入门之get网页信息并作为文本输出
    Checker
    Manacher模板
    POJ3974——Palindrome
    Seek the Name, Seek the Fame
  • 原文地址:https://www.cnblogs.com/Troverld/p/14621729.html
Copyright © 2011-2022 走看看