zoukankan      html  css  js  c++  java
  • [BZOJ 1006] [HNOI2008] 神奇的国度 【弦图最小染色】

    题目链接: BZOJ - 1006

    题目分析

    这道题是一个弦图最小染色数的裸的模型。

    弦图的最小染色求法,先求出弦图的完美消除序列(MCS算法),再按照完美消除序列,从后向前倒着,给每个点染能染的最小颜色。

    求出的颜色数就是最小染色,同时也是最大团。

    代码

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    const int MaxN = 10000 + 5, MaxM = 1000000 + 5;
    
    int n, m, Ans;
    int V[MaxN], A[MaxN], Col[MaxN], Used[MaxN];
    
    bool Visit[MaxN];
    
    struct Edge
    {
    	int v;
    	Edge *Next;
    } E[MaxM * 2], *P = E, *Point[MaxN];
    
    inline void AddEdge(int x, int y) 
    {
    	++P; P -> v = y; 
    	P -> Next = Point[x]; Point[x] = P;
    }
    
    struct ES
    {
    	int p, q;
    	ES() {}
    	ES(int a, int b) 
    	{
    		p = a; q = b;
    	}
    };
    
    struct Cmp
    {
    	bool operator () (ES e1, ES e2)
    	{
    		return e1.q < e2.q;
    	}
    };
    
    priority_queue<ES, vector<ES>, Cmp> Q;
    
    //MCS 求完美消除序列 
    void MCS() 
    {
    	for (int i = 1; i <= n; ++i) 
    	{
    		V[i] = 0;
    		Visit[i] = false;
    	}
    	while (!Q.empty()) Q.pop();
    	Q.push(ES(1, 0));
    	int x, y;
    	for (int i = n; i >= 1; --i) 
    	{
    		while (true) 
    		{
    			x = Q.top().p; Q.pop();
    			if (!Visit[x]) break;
    		}
    		A[i] = x;
    		Visit[x] = true;
    		for (Edge *j = Point[x]; j; j = j -> Next) 
    		{
    			y = j -> v;
    			if (Visit[y]) continue;
    			++V[y];
    			Q.push(ES(y, V[y]));
    		}
    	}
    }
    
    void Min_Paint() 
    {
    	Ans = 1;
    	int x;
    	memset(Col, 0, sizeof(Col));
    	memset(Used, 0, sizeof(Used));
    	for (int i = n; i >= 1; --i) 
    	{	
    		for (Edge *j = Point[A[i]]; j; j = j -> Next) 
    			Used[Col[j -> v]] = i;
    		x = 1;
    		while (Used[x] == i) 
    		{
    			++x;
    			if (x > Ans) Ans = x;
    		}
    		Col[A[i]] = x;
    	}
    }
    
    int main() 
    {
    	scanf("%d%d", &n, &m);
    	int a, b;
    	for (int i = 1; i <= m; ++i) 
    	{
    		scanf("%d%d", &a, &b);
    		AddEdge(a, b);
    		AddEdge(b, a);
    	}
    	MCS();
    	Min_Paint();
    	printf("%d
    ", Ans);
    	return 0;
    }
    

      

  • 相关阅读:
    NHibernate连接Oracle配置问题
    事件之 textField
    加入了有生命力的团队
    亲临 Adobe CS4 新产品发布会
    flash打开exe程序
    Lite:AMC MMI
    Lite:SharedObject对象保存数据 到Pc 或手机
    忙忙碌碌
    as3.0过渡完毕,用as3 做了几个Air程序
    getURL("mailTo:wangnai789@sina.com")给多人发送邮件
  • 原文地址:https://www.cnblogs.com/JoeFan/p/4304516.html
Copyright © 2011-2022 走看看