zoukankan      html  css  js  c++  java
  • 【BZOJ】1006: [HNOI2008]神奇的国度

    http://www.lydsy.com/JudgeOnline/problem.php?id=1006

    题意:在一个弦图中找最少染色数。(n<=10000, m<=1000000)

    #include <bits/stdc++.h>
    using namespace std;
    const int N=10005, M=1000005;
    int n, m, ihead[N], tag[N], cnt, pos[N];
    bool vis[N];
    struct E { int next, to; }e[M<<1];
    void add(int u, int v) {
    	e[++cnt]={ihead[u], v}; ihead[u]=cnt;
    	e[++cnt]={ihead[v], u}; ihead[v]=cnt;
    }
    #define pii pair<int, int> 
    #define mkpii make_pair<int, int>
    set<pii> s;
    inline int getmx() {
    	set<pii>::iterator it=s.end(); --it;
    	int ret=(*it).second;
    	s.erase(s.find(mkpii((*it).first, ret)));
    	return ret;
    }
    inline void fix(int x) {
    	s.erase(s.find(mkpii(tag[x], x)));
    	++tag[x];
    	s.insert(mkpii(tag[x], x));
    }
    int getans() {
    	int ret=0;
    	for(int i=1; i<=n; ++i) s.insert(mkpii(0, i));
    	for(int now=n; now; --now) {
    		int x=getmx(), ans=1;
    		pos[x]=now;
    		for(int i=ihead[x]; i; i=e[i].next) if(!pos[e[i].to]) fix(e[i].to);
    		for(int i=ihead[x]; i; i=e[i].next) if(pos[e[i].to]>pos[x] && !vis[e[i].to]) ++ans, vis[e[i].to]=1;
    		for(int i=ihead[x]; i; i=e[i].next) if(pos[e[i].to]>pos[x]) vis[e[i].to]=0;
    		ret=max(ret, ans);
    	}
    	return ret;
    }
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i=0; i<m; ++i) {
    		int x, y;
    		scanf("%d%d", &x, &y);
    		add(x, y);
    	}
    	printf("%d
    ", getans());
    	return 0;
    }
    

      

    题解:

    定理1:色数>=团数

    定理2:最小色数=极大团数

    定理1不会证QAQ(如此显然的东西竟然没看出来?

    定理2挺简单的,看cdq论文= =

    所以我们找最大的团就行了= =

    于是就完了= =

    用set维护了一下最大= =因为链表的话感觉很麻烦写= =

  • 相关阅读:
    14.使用nodejs将规定格式的txt转化为json数据
    13.resize妙用(书上看到的)
    12.写了一个怪怪的边框
    11.一起来抄一个小小的提示菜单
    UI02-textfiled.按钮 uibutton
    UI01-UIview UIlable的属性
    OC9-内存管理
    OC8-属性 KVC是键值编码
    OC7-‍ 类目,延展 协议代理。
    OC6-block-函数指针
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4293953.html
Copyright © 2011-2022 走看看