算法 结构

1、//在n×n格的棋盘上放置彼此不受攻击的n(3<n<11)个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜上的棋子。 n后问题等价于在 n×n格的棋盘上放置n个皇后,任何 2个皇后不放在同一行或同一列或同一斜线上。使用FIFO-分支限界法求解 n 皇后问题,输出在 n×n个方格上放置彼此不受攻击的n个皇后的一个放置方案。输入一个正整数n。输出第一个n个皇后的放置方案(行和列号都从1开始,每个数字后带有一个空格)。样例输入 Copy4样例输出 Copy2 4 1  3

#include<iostream>
#include<algorithm>
using namespace std;
int Queen[100],n,l=0;	//l用来求递归了几次,题目只求一次,那么一次就输出就行
void dfsQueen(int k){	
	if(k==n&&l==0){	//证明已经摆完 ,输出
		for(int i=0;i<n;i++){
			cout<<Queen[i]+1<<" ";
		} 
		l++;
		return;
	}
	for(int i=0;i<n;i++){	//每次循环判断n列中没与前面k行中的皇后有相连的情况
		int j;
		for(j=0;j<k;j++){
			if(Queen[j]==i||abs(k-j)==abs(Queen[j]-i)){	//有相连情况直接跳出
				break;
			}
		}
		if(j==k){	//如果j等于k则证明当前这一列可以放置皇后,递归该列
			Queen[k]=i;	
			dfsQueen(k+1);
		}
	}
}
main()
{
	cin>>n;
	dfsQueen(0);
}

2、一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。

输入:第一行两个整数,分别表示n 和 e 的值(1 <= n <= 2 * 10^5,  0 <= e <= 2 * 10^5);

下面e行,每行两个整数,分别表示一条边的两个顶点;

最后一行两个整数,分别表示 source 和 destination的值。

输出:若存在从顶点 source到顶点 destination的路径,则输出true;否则,输出false。

样例输入 Copy

3 3

0 1

1 2

2 0

0 2

样例输出 Copy

true

#include<bits/stdc++.h>
using namespace std;
int fa[15];
 
int find(int x)
{
	if (fa[x] == x)
		return x;
	else
		return fa[x] = find(fa[x]);
}
 
void merge(int x, int y)
{
	int fa_x = find(x);//找x的祖先
	int fa_y = find(y);//找y的祖先
	if (fa_x != fa_y)//如果x,y的祖先不是一个元素
		fa[fa_x] = fa_y;//x的祖先指向y的祖先
}
 
int main()
{
	int i, j, n, m, a, b, k1, k2;
	for (i = 0; i < 15; i++)
    {
		fa[i] = i;//初始化,每个人的祖先都是自己本身
	}
	cin >> n >> m;
	for (i = 0; i < m; i++) 
    {
		cin >> a >> b;
		merge(a, b);
	}
	cin >> k1 >> k2;
	if(find(k1) == find(k2))
		printf("true");
	else
		printf("false");
	return 0;
}

3、给定无向连通图G=(V, E),该图有n个顶点,e条边。用m种颜色对G中的顶点着色,使得任意两个相邻顶点着色不同。输出着色后的所有可能的结果。

输入

第一行三个整数,分别表示n,e 和 m 的值。1<=n,m<=10。
下面e行,每行二个整数,表示边的两个顶点,顶点编号为0,1,2,...,n-1。

输出

如果能用m种颜色着色,输出染色后的所有可能的结果(输出顺序见样例);否则输出No solution。

样例输入 Copy
4 5 3
0 1
0 3
1 2
1 3
2 3
样例输出 Copy
1 2 1 3
1 3 1 2
2 1 2 3
2 3 2 1
3 1 3 2
3 2 3 1

#include <bits/stdc++.h>
   
using namespace std;  
bool flag=true; 
// 检查是否可以给顶点v上色为color  
bool isValid(const vector<vector<int>>& graph, vector<int>& colors, int v, int color) {  
    for (int u : graph[v]) {  
        if (colors[u] == color) {  
            return false;  
        }  
    }  
    return true;  
}  
   
// 图的着色函数  
void graphColoring(const vector<vector<int>>& graph, int n, int m, int v, vector<int>& colors) {  
    if (v == n) {  
     flag=false;
        // 所有顶点都已着色,打印结果  
        for (int i = 0; i < n; ++i) {  
            cout << (i > 0 ? " " : "") << colors[i] + 1;  
        }  
        cout << endl;  
        return;  
    }  
   
    for (int color = 0; color < m; ++color) { // 注意颜色从0开始计数,但输出时需要+1  
        if (isValid(graph, colors, v, color)) {  
            colors[v] = color;  
            graphColoring(graph, n, m, v + 1, colors);  
            // 回溯  
            colors[v] = -1; // 还原颜色,这里用-1表示未着色  
        }  
    }  
}  
   
int main() {  
    int n, e, m;  
    cin >> n >> e >> m;  
   
    vector<vector<int>> graph(n);  
    for (int i = 0; i < e; ++i) {  
        int u, v;  
        cin >> u >> v;  
        graph[u].push_back(v);  
        graph[v].push_back(u); // 无向图,双向添加  
    }  
   
    vector<int> colors(n, -1); // 初始化颜色数组,-1表示未着色  
   
    // 尝试进行着色  
    graphColoring(graph, n, m, 0, colors);  
   
    // 如果未找到任何着色方案,则输出No solution  
    if (flag==true) {  
        cout << "No solution" << endl;  
    }  
   
    return 0;  
}
#include<bits/stdc++.h>
using namespace std;
int n,e,m; 
int flag;//记录有效的着色方案数量
int g[10][10];//g=1边存在 
int co[10];//颜色函数 
bool is_valid(int v,int c){//检查顶点 v 是否可以被上色 c。
	for(int i=0;i<n;i++){//检查 v 相邻的所有顶点,
	    if(g[v][i] &&co[i]==c){//确保没有两个相邻顶点具有相同的颜色来
	    	return false;
		}
	} 
	return true;
}
void df(int v){//深度优先搜索图的所有可能的着色方案
	if(v==n){//对n个顶点都上色后,一次上色结束 (递归出口) 
		flag++;//着色方案数量+1 
		for(int i=0;i<n;i++){//输出 
			cout<<co[i]<<" "; 
		}
		cout<<endl;
		return ;//一次递归结束 
	}
	for(int i=1;i<=m;i++){//分别依次对m个颜色 
		if(is_valid(v,i)){//判断颜色i可以对点v上色 
			co[v]=i;//上色 
			df(v+1);//处理下一个顶点 
			// 重置当前顶点的颜色: 
			co[v]=0;//一次递归结束 
		}
	}
}
int main(){
	cin>>n>>e>>m;//n个顶点,e条边。用m种颜色对G中的顶点着色

	for(int i=0;i<e;i++){
		int x,y;cin>>x>>y;
		g[x][y]=1;g[y][x]=1;//边 
	}
	df(0);
	if(flag==0) cout<<"No solution";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值