day1 图论(1)

拓扑排序

输出字典序最小的拓扑排序
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。

bool mp[MAXN][MAXN];
int input[MAXN];  //入度
priority_queue<int,vector<int>,greater<int> >q; 
int n,m;

void work(int n){
	for(int i=1;i<=n;i++){
		if(input[i] == 0){  //把入度为0的点放进去 
			q.push(i);
		}
	}
	int p=1;
	while(!q.empty()){
		int now = q.top();
		q.pop();
		if(p != n){
			cout << now << " ";
			p++;
		}
		else cout << now << endl;
		for(int i=1;i<=n;i++){
		if(!mp[now][i])continue;
		input[i] --;
		if(input[i] == 0)q.push(i);
	}
	}
}
void init(){
	memset(mp,0,sizeof(mp));
	memset(input,0,sizeof(input));
}
int main(){
	while(cin >> n >> m){
		init();
		int x,y;
		while(m--){
			cin >> x >> y;
			if(!mp[x][y]){
			   mp[x][y] = 1;
			   input[y] ++;	
			}
		}
		work(n);
	}
	return 0;
}

[欧拉回路]题目

欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
无向图:
1.全是偶点,存在欧拉回路
2.只有两个奇点,存在欧拉路

有向图:
把一个点出度为1,入度为-1,欧拉回路度数全为零,欧拉通路只有一个1,一个-1,其他都是0;

vector<int>e[MAXN];
int vis[MAXN]; 
int n,m;

void init(){
	for(int i=0;i<MAXN;i++)e[i].clear();
	memset(vis,0,sizeof(vis));
}
void dfs(int x){    //判断联通
	int n = e[x].size();
	vis[x] = 1;
	for(int i=0;i<n;i++){
		int now = e[x][i];
		if(vis[now] == 0){
			vis[now] = 1;
			dfs(now);
		}
	}
} 
int main(){   //判断是否存在欧拉回路 
	//联通且都是偶点
	while(cin >> n && n){
		cin >> m;
		init();
		while(m--){
			int x,y;
			cin >> x >> y;
			e[x].push_back(y);
			e[y].push_back(x);
		}
		dfs(1);  //找联通 
		int i;
		for(i=1;i<=n;i++){
			if(!vis[i] || (e[i].size() & 1) )break; //不连通或者有奇点
		}
		if(i != n+1){
			cout << "0" << endl;
			continue;
		}
		cout << "1" << endl;
	}
	return 0; 
}

hdu1116 play on words

把单词首尾连起来,然后看能不能连成一行

[思路]:先用并查集是否连通,然后用点的入度出度判断是否是欧拉路径.(可以是环)

int fa[30],in[30],out[30];
bool vis[30];

int find_set(int x){return fa[x] == x?x:fa[x] = find_set(fa[x]);}
void merge_set(int x,int y){
	x = find_set(x);
	y = find_set(y);
	if(x != y){fa[x] = y;}
}
int cc;
string s;

int main(){
	cin >> cc;
	while(cc--){
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		memset(vis,0,sizeof(vis));
		for(int i=1;i<MAXN;i++)fa[i] = i;
		int n;cin >> n;
		while(n--){
			cin >> s;
			int lena = s.length();
			int l = s[0]-'a'+1;
			int r = s[lena-1]-'a'+1;
			out[l]++;in[r]++;
			vis[l] = 1;vis[r] = 1;
			merge_set(l,r);
		}
		
		int root=0,inin=0,ouou=0,f = 1;
		for(int i=1;i<MAXN;i++){
			if(vis[i]){
				if(fa[i] == i)root ++;
				if(in[i] != out[i]){
					if(in[i] - out[i] == 1)inin++;
					else if(out[i] - in[i] == 1)ouou++;
					else f = 0;
				}
			}
			if(root > 1){
				f = 0;
				break;
			}
		}
		
		if((f && (inin==0) && (ouou==0)) || (f && (inin == 1) && (ouou == 1))){
			cout << "Ordering is possible." << endl;
		}
		else cout << "The door cannot be opened." << endl;	
	}
	return 0;
}

深搜优先生成树求割点
在一个连通分量G中,对任意一个点s做DFS,能访问到所有点,产生一棵“深搜优先生成树”T。

定理1:T的根结点s是割点,当且仅当s有2个或更多的子结点。
定理2:T的非根结点u是割点,当且仅当u存在一个子结点v,v及其后代都没有回退边连回u的祖先。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值