11月22日天梯赛补题

图着色问题

图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?

但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。

输入格式:
输入在第一行给出3个整数V(0<V≤500)、E(≥0)和K(0<K≤V),分别是无向图的顶点数、边数、以及颜色数。顶点和颜色都从1到V编号。随后E行,每行给出一条边的两个端点的编号。在图的信息给出之后,给出了一个正整数N(≤20),是待检查的颜色分配方案的个数。随后N行,每行顺次给出V个顶点的颜色(第i个数字表示第i个顶点的颜色),数字间以空格分隔。题目保证给定的无向图是合法的(即不存在自回路和重边)。

输出格式:
对每种颜色分配方案,如果是图着色问题的一个解则输出Yes,否则输出No,每句占一行。

题解:用一个vector数组来存储信息。遍历,如果俩个联通的位置颜色一样,则不可以。
#include<bits/stdc++.h>

using namespace std;

vector<int >f[1505];

int d[1505];
int v,e,k;
set<int>s;

int judge()
{
	for(int i=1;i<=v;i++){
		for(int j=0;j<f[i].size();j++){
			if(d[i]==d[f[i][j]]){
				return 0;
			}
		}
	}
	return 1;
}

int main(){
    cin>>v>>e>>k;
    for(int i=0;i<e;i++){
        int a,b;
        cin>>a>>b;
        f[a].push_back(b);
        f[b].push_back(a);
    }
    int t;
    cin>>t;
    while(t--){
        s.clear();
        memset(d,0,sizeof(d));
        for(int i=1;i<=v;i++){
            cin>>d[i];
            s.insert(d[i]);
        }
        if(s.size()!=k){
            cout<<"No"<<endl;
        }
        else{
            int x=judge();
            if(x==1){
                cout<<"Yes"<<endl;
            }
            else{
                cout<<"No"<<endl;
            }
        }
    }
}

列车调度

火车站的列车调度铁轨的结构如下图所示。

两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?

输入格式:
输入第一行给出一个整数N (2 ≤ N ≤10
​5
​​ ),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。

输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。

输入样例:
9
8 4 2 5 3 9 1 6 7
输出样例:
4

题解:

对于每辆进入的列车找到最大小于他的那个列车,排在他的后面,如果他是最小的。则需要重新开一条隧道。使用set数组中的upper_bound即可轻松解决。

#include<cstdio>
#include<iostream>
#include<set>

using namespace std;

int main(){
	int n,t;
	cin>>n;
	set <int> q;
	for(int i=0;i<n;i++){
		cin>>t;
		if(q.upper_bound(t)!=q.end()){
            q.erase(q.upper_bound(t));
		}
		q.insert(t);
	}
	cout<<q.size()<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值