CF 36E Two Paths

本文深入探讨了欧拉回路算法在解决复杂图论问题中的应用,包括如何处理不连通图和奇点配对,通过实例解析算法实现细节,如添加边以确保路径连通性,以及如何利用栈结构进行欧拉路径遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

真实的自闭= =+

考试的时候老师明明说了可以路径为空T^T

然后光荣的挂掉了 20分的链【明明是最送分的】

上来就看出来欧拉回路了嘛 然后思考了一下大概奇点配个对 删一条简单路径剩下的跑欧拉路径就好了嘛 然后就冒出来了这个东西

如果简单路径删了的话 图就不连通了= =||

心态崩塌【后来发现数据没卡这玩意T^T】

想新加边 但是发现这样就变成三段路径了= =||

然后孙神一眼切表示你强制第一步走新加的边就好了嘛

我好菜啊QAQ

于是就剩下一堆【真实的一堆】奇奇怪怪的细节

于是今天上午机房里弥漫着愉悦的hack气氛

具体处理什么的看代码吧QwQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std;

struct edge{int to,lt;}e[mxn<<1];
int d[mxn],cnt=1,in[mxn],n,m;
void add(int x,int y)
{
	e[++cnt].to=y;e[cnt].lt=in[x];in[x]=cnt;
	e[++cnt].to=x;e[cnt].lt=in[y];in[y]=cnt;
}
stack<int> st;bool vis[mxn],ag[mxn];
void eulerpath(int x)
{
	ag[x]=1;
	for(int &t=in[x];t;t=e[t].lt)
	{
		if(vis[t>>1])	continue;
		vis[t>>1]=1;int id=t>>1;
		eulerpath(e[t].to);
		st.push(id);
	}
}
int inq[mxn],sz;
void dfs(int x,int col)
{
	inq[x]=col;sz++;
	for(int i=in[x];i;i=e[i].lt)
	{
		if(inq[e[i].to])	continue;
		dfs(e[i].to,col);
	}
}
int q[6],tot;
int ans[mxn];
bool solve()
{
	if(m<2)	return false;
	int ltk=0,start[3];int i,nxt=0;
	for(int i=1;i<=n;i++)
	{
		if(!inq[i])
		{
			sz=0;dfs(i,ltk+1);
			if(sz>1)	start[++ltk]=i;
		}
	}
	if(ltk>2)	return false;
	for(int i=1;i<=n;i++)
	{
		if(d[i]&1)	q[++tot]=i;
		if(tot>4)	break;
	}
	if(tot>4)	return false;
	if(tot==2)	add(q[1],q[2]);
	if(tot==4)
	{
		if(ltk==2&&inq[q[1]]==inq[q[2]]&&inq[q[2]]==inq[q[3]])	return false;
		for(i=2;i<5;i++)	if(inq[q[i]]==inq[q[1]])	break;
		add(q[i],q[1]);
		if(i==2)	nxt=3,add(q[3],q[4]);
		if(i==3)	nxt=4,add(q[2],q[4]);
		if(i==4)	nxt=2,add(q[2],q[3]);
	}
	eulerpath(tot?q[1]:start[1]);
	int dis=0;
	if(!st.empty()&&st.top()>m)	st.pop();
	while(!st.empty())
	{
		int x=st.top();st.pop();
		if(x>m)	break;
		ans[++dis]=x;
	}
	if(dis==m)
	{
		//printf("QAQ");
		printf("%d\n",dis-1);
		for(int i=1;i<dis;i++)	printf("%d ",ans[i]);
		printf("\n");
		printf("%d\n%d\n",1,ans[dis]);
		return true;
	}
	printf("%d\n",dis);
	for(int i=1;i<=dis;i++)	printf("%d ",ans[i]);
	printf("\n");
	int tou=0;
	if(tot==4){if(!ag[q[nxt]])eulerpath(q[nxt]),tou=1;}
	else if(ltk==2){if(!ag[start[2]])eulerpath(start[2]);if(!ag[start[1]])eulerpath(start[1]);}
	dis=0;
	if(tou)	if(st.top()>m)	st.pop();
	while(!st.empty())
	{
		int x=st.top();st.pop();
		if(x>m)	break;
		ans[++dis]=x;
	}
	printf("%d\n",dis);//printf("QAQ");
	for(int i=1;i<=dis;i++)	printf("%d ",ans[i]);
	return true;
}
int main()
{
	int x,y;
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)	scanf("%d%d",&x,&y),add(x,y),d[x]++,d[y]++;
	if(!solve())	printf("-1\n");
	return 0;
}

这一份是考试的改的 那个读入什么的有一些偏差qwq

转载于:https://www.cnblogs.com/hanyuweining/p/10321930.html

在使用 Vivado 实现 FIFO(尤其是 FIFO36E2)时,需要特别注意 FIFO 的配置、时序约束以及在仿真和综合阶段可能出现的问题。以下是一些关键点和常见错误的排查建议。 ### FIFO36E2 的基本配置 FIFO36E2 是 Xilinx 提供的一种高性能 FIFO IP 核,支持异步和同步模式,适用于多种数据宽度和深度的配置。使用 Vivado 生成 FIFO36E2 的步骤通常包括: 1. **打开 IP Integrator**,选择“Create Block Design”。 2. **添加 FIFO Generator IP**,设置 FIFO 的读写宽度、深度、模式(同步/异步)等参数。 3. **配置 FIFO 的状态标志**,如空(empty)、满(full)、几乎空(almost_empty)、几乎满(almost_full)等,这些标志可用于控制读写操作。 4. **生成并集成 IP**,将其添加到设计中,并连接相应的信号线。 ### Implementation 过程中的关键步骤 Vivado 的 Implementation 过程主要包括以下几个阶段: - **opt_design**:优化设计,生成 `opt_design.dcp` 文件。 - **place_design**:布局设计,生成 `place_design.dcp` 文件。 - **route_design**:布线设计,生成 `route_design.dcp` 文件。 在 Implementation 阶段,需要确保设计满足时序约束。如果 FIFO 的读写时钟域之间存在时序问题,可能会导致 FIFO 无法正常工作。可以通过时序分析工具检查路径延迟,并适当调整约束条件。 ### 常见错误及调试方法 #### 1. **仿真中数据读出为 0** 在仿真过程中,如果发现 FIFO 写入成功但读出的数据为 0,可能是由于仿真精度设置不当。默认情况下,Vivado 生成的 FIFO 的 `timescale` 精度为 `1ns/1ps`。如果仿真时设置的精度为 `1ps/1ps`,可能会导致数据无法正确写入 FIFO。解决方法是确保仿真精度与 FIFO 的 `timescale` 一致,即设置为 `1ns/1ps` [^2]。 #### 2. **FIFO 深度不一致** 在配置 FIFO 时,虽然写深度设置为 256,但实际实现的深度可能为 255。这是因为 FIFO 的深度是根据写宽度和读宽度自动计算的,通常需要满足以下关系: ```math 写宽度 \times 写深度 = 读宽度 \times 读深度 ``` 如果发现 FIFO 的实际深度与预期不符,应检查写宽度、读宽度以及深度的设置是否符合上述关系 [^4]。 #### 3. **状态标志异常** FIFO 的状态标志(如 empty、full)可能会出现异常,导致读写操作无法正确触发。这通常是由于时钟域之间的同步问题引起的。可以考虑在状态标志的输出端添加同步 FIFO 或使用异步复位信号来确保状态标志的稳定性。 #### 4. **时序违例** 在 Implementation 阶段,可能会遇到时序违例的问题,尤其是在异步 FIFO 中。可以通过以下方式解决: - **添加时序约束**:确保 FIFO 的读写时钟域之间有正确的时序约束。 - **使用异步 FIFO**:如果读写时钟频率差异较大,建议使用异步 FIFO 来避免跨时钟域的问题。 - **优化布局**:通过调整布局策略,减少信号路径延迟。 ### 示例代码 以下是一个简单的 FIFO 读写控制逻辑的 Verilog 代码示例: ```verilog module fifo_control ( input wire wr_clk, input wire rd_clk, input wire rst, output reg wr_en, output reg rd_en, input wire empty, input wire full ); always @(posedge wr_clk or posedge rst) begin if (rst) wr_en <= 1'b0; else if (!full) wr_en <= 1'b1; else wr_en <= 1'b0; end always @(posedge rd_clk or posedge rst) begin if (rst) rd_en <= 1'b0; else if (!empty) rd_en <= 1'b1; else rd_en <= 1'b0; end endmodule ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值