图论:弦图最小点染色

弦图的定义:当图中任意长度大于3的环都至少有一个弦时, 一个无向图称为弦图

不存在四角、五角等关系就说明这个图是一个弦图

题目问的是,任何一对相互认识的人不可以组一队,问最多可以组多少对

所有的人构成的关系图是一个弦图(长度超过 3 的环中必有一条弦),求出它的完美性消除序列,根据完美消除序列逆序贪心的染色,最终所用的色数就是本题的答案

好难啊

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<cstring>
 6 #define inf 0x7fffffff
 7 #define ll long long
 8 using namespace std;
 9 inline ll read()
10 {
11     ll x=0,f=1;char ch=getchar();
12     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 int n,m,cnt,ans;
17 int head[10005],d[10005],q[10005],col[10005],hash[10005];
18 bool vis[10005];
19 struct data{int to,next;}e[2000005];
20 void ins(int u,int v)
21 {e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
22 int main()
23 {
24     n=read();m=read();
25     for(int i=1;i<=m;i++)
26     {
27         int u=read(),v=read();
28         ins(u,v);ins(v,u);
29     }
30     for(int i=n;i;i--)
31     {
32         int t=0;
33         for(int j=1;j<=n;j++)
34         {
35             if(!vis[j]&&d[j]>=d[t])t=j;
36         }
37         vis[t]=1;q[i]=t;
38         for(int j=head[t];j;j=e[j].next)
39             d[e[j].to]++;
40     }
41     for(int i=n;i>0;i--)
42     {
43         int t=q[i];  
44         for(int j=head[t];j;j=e[j].next)hash[col[e[j].to]]=i;
45         int j;
46         for(j=1;;j++)if(hash[j]!=i)break;
47         col[t]=j;
48         if(j>ans)ans=j;
49     }
50     printf("%d",ans);
51     return 0;
52 }

 再补上一些区间图的定义和应用

给定一些区间,定义一个相交图为每个顶点表示一个区间,两个点有边当且仅当两个区间的交集非空。

一个图为区间图当它是若干个区间的相交图

区间图一定是弦图

应用有

1.给定n个区间,要求选择最多的区间使得区间不互相重叠。

区间图的最大独立集。

2.有n个积木,高度均为1,第i个积木的宽度范围为[Li, Ri],选择一个积木的下落顺序使得最后积木总高度尽可能小。

把一层积木看成一个颜色,转化为区间图的色数问题。

好像解法依赖于一个极其复杂的数据结构?

posted @ 2018-09-10 23:20  静听风吟。  阅读(612)  评论(0编辑  收藏  举报