图型学习指南

典题合集

前置芝士

菊花图

若无向简单图G满足,存在一个点v为支配点,其余点之间没有边相连,则称G为菊花图。

最大团

最大团问题(Maximum Clique Problem)是图论中的一个经典问题,是指在一个无向图中找到具有最大顶点数的完全子图(即每两个顶点之间都有直接的边相连)。
如果一个团不能通过加入某个新的顶点来扩展成一个更大的团,那么该团就被称为最大团。

判断菊花图||一条链

The decomposition is the splitting the edges of the tree in some simple paths in such a way that each two paths have at least one common vertex. Each edge of the tree should be in exactly one path.

//n=1e5
const int N=1e5+10;
int n;
int d[N],cnt=0,r;
void solve(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		if(++d[u]==3) cnt+=1,r=u;
		if(++d[v]==3) cnt+=1,r=v;
	}
	if(cnt==0){
		cout<<"Yes"<<endl;
		cout<<1<<endl;
		for(int i=1;i<=n;i++) if(d[i]==1) cout<<i<<" ";
		cout<<endl;
	}
	else if(cnt==1){
		cout<<"Yes"<<endl;
		for(int i=1;i<=n;i++) if(d[i]==1) cnt++;
		cout<<cnt-1<<endl;
		for(int i=1;i<=n;i++) if(d[i]==1) cout<<i<<" "<<r<<endl;
	}else{
		cout<<"No"<<endl;
	}
}

最大团

[problem description]

在一个无向图中,如果一个顶点子集满足子集内的任意两个不同顶点之间都是相连的,那么这个顶点子集就被称为一个团。

如果一个团不能通过加入某个新的顶点来扩展成一个更大的团,那么该团就被称为最大团。

现在,你需要判断给定顶点子集能否构成一个最大团。

[input]

第一行包含两个整数n和m,分别表示无向图中点和边的数量。

接下来m行,每行包含两个整数 a,b,表示点 a 和点 b 之间存在一条边。

所有点的编号从 1 到n。

再一行,包含整数q,表示询问次数。

接下来q行,每行描述一个询问顶点子集,首先包含一个整数k,表示子集包含点的数量,然后包含k个整数,表示k个不同顶点的编号。一行中所有数字之间用一个空格隔开。

[output]

每组询问在一行中输出一个结论。

如果给定子集是最大团,则输出 Yes,如果是一个团,但不是最大团,则输出 Not Maximal,如果根本不是团,则输出 Not a Clique

[datas]

1≤n≤200
1≤m≤n(n−1)/2
1≤q≤100
1≤K≤n

[solved]

判断可行解,先判断是否任意两点都直接连接,再判断其他点是否有与集中的点全部连接的点。

const int N = 210;

int n, m, q;
int e[N][N];
int a[N];
void sol() {
    int k;
    cin>>k;
    vector<int> cnt(n+1,0);
    for (int i = 1; i <= k; i++) cin >> a[i];
    for (int i = 1; i <= k; i++)
        for (int j = i + 1; j <= k; j++) {
            if (!e[a[i]][a[j]]) {cout << "Not a Clique" << endl;return;}
        }
    for(int i=1;i<=k;i++){
        for(int j=1;j<=n;j++){
            if(e[a[i]][j]) cnt[j]+=1;
        }
    }
    for(int i=1;i<=k;i++) cnt[a[i]]=0;
    for(int i=1;i<=n;i++) if(cnt[i]==k) {cout<<"Not Maximal"<<endl;return;}
    cout<<"Yes"<<endl;
}
void solve() {
    //freopen("a.in","r",stdin);
    //freopen("a.out","w",stdout);
    cin >> n >> m;
    for (int i = 1, x, y; i <= m; i++) {
        cin >> x >> y;
        e[x][y] = 1;;
        e[y][x] = 1;
    }
    cin >> q;
    while (q--) {
        sol();
    }
}
posted @ 2023-11-21 21:26  White_Sheep  阅读(12)  评论(0编辑  收藏  举报