图论:弦图最小点染色
弦图的定义:当图中任意长度大于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],选择一个积木的下落顺序使得最后积木总高度尽可能小。 把一层积木看成一个颜色,转化为区间图的色数问题。
好像解法依赖于一个极其复杂的数据结构?