Day2 欧拉路,拓扑排序和差分约束

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/87005491

A.BZOJ 3033: 太鼓达人

题目

BZOJ 3033

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e3+50;
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1,ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
int n,t,ans[maxn];
bool used[maxn];
inline bool eular(int x,int k)//x是当前子串的十进制表示,k是当前查询次
{
	if (used[x]) return 0;
	used[x]=1,ans[k]=x&1;//统计答案,&的规则是:有零则零,否则为一,返回末位数字
	if (k==t) return 1;//查询结束
	if (eular((x<<1)&(t-1),k+1)) return 1;
	if (eular((x<<1|1)&(t-1),k+1)) return 1;//将每个二进制数看成一个点,将他前面的数删去,并在它后面加上0/1就能得到两个新数
	used[x]=0;//回溯,以免影响之后的dfs
	return 0;
}
int main()
{
	read(n);
	t=1<<n;
	printf("%d ",t);
	eular(t-2,1);//从每位走n位子串,可得到的完整子串数量为2^n-2
	for (int i=1;i<=t;++i)
		printf("%d",ans[i]);
	return 0;
}

邱神版本:

#include<bits/stdc++.h> 
using namespace std;
int read()
{
	int a;
	cin>>a;
	return a;
}
int i,k,m;
struct node
{
	int x,deep;
}o[10010];
bool Orz(node a,node b)
{
	return a.deep<b.deep;
}
void dfs(int now,int deep)
{
	if(deep==m+1)
	{
		now=now%(m/2);
		now=now*2;
		if(now)
			return ;
		sort(o,o+m,Orz);
		for(i=1;i<k;i++)
			cout<<0;
		for(i=0;i<=m-k;i++)
			cout<<o[i].x%2;
		
		exit(0) ;
	}
	//这里应该有一个关于deep和now的if使得dfs停下来并输出
	now=now%(m/2);
	now=now*2;
	if(!o[now].deep)
	{	
		o[now].deep=deep;
		dfs(now,deep+1);
		o[now].deep=0;
	}
	now++;
	if(!o[now].deep)
	{
		o[now].deep=deep;
		dfs(now,deep+1);
		o[now].deep=0;
	}
	return ;
}
int main()
{	
	//freopen("123.in","r",stdin);
	k=read();m=int(pow(2,k*1.0));
	cout<<m<<' ';
	for(i=0;i<m;i++)
		o[i].x=i;
	o[0].deep=1;
	dfs(0,2);
}

B. POJ 1386 Play on Words

题目

POJ 1386

题解

其实就是让判断是否是欧拉回路或欧拉通路.
建图需要一点思维,把26个字母当成是节点,每个单词当成是一条有向边。
比如单词 a c m acm 就是一条 a a m m 的有向边。
然后用并查集判断图是否联通即可。

代码

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=30;
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1,ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
int fa[maxn];
inline int get(int x)
{
	if (x==fa[x]) return x;
	return fa[x]=get(fa[x]);
}
int indeg[maxn],outdeg[maxn];
int main()
{
	int t;read(t);
	while (t--)
	{
		int n;read(n);
		memset(indeg,0,sizeof(indeg));
		memset(outdeg,0,sizeof(outdeg));
		for (int i=0;i<26;++i)
			fa[i]=i;
		char str[1005];
		for (int i=1;i<=n;++i)
		{
			scanf("%s",str);
			int x=str[0]-'a';
			int y=str[strlen(str)-1]-'a';
			if (get(x)!=get(y))
				fa[get(x)]=get(y);
			++indeg[y],++outdeg[x];
		}
		bool flag=true;
		int cnt=0,In=0,Out=0;
		for (int i=0;i<26;++i)
		{
			if (get(i)==i && (indeg[i]+outdeg[i])>0)
				++cnt;
			if (indeg[i]!=outdeg[i])
			{
				if (indeg[i]-1==outdeg[i])
					++In;
				else if (indeg[i]+1==outdeg[i])
					++Out;
				else
					flag=false;
			}
		}
		if (flag && cnt==1 && (In==1 && Out==1 || In==0 && Out==0))
			puts("Ordering is possible.");//欧拉回路和通路都符合题目条件
		else
			puts("The door cannot be opened.");
	}
	return 0;
}

C. CF 516B. Drazil and Tiles

题目

CF 516B

代码

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=2e3+2;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
const char ch[]="><v^";
const char str[]="<>^v";
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1,ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
struct rec
{
	int x,y;
}a[maxn*maxn];
int m,n,tot,G[maxn][maxn];
char c[maxn][maxn];
inline bool check(int x,int y)
{
	return x>0 && x<=m && y>0 && y<=n;
}
inline void dfs(int x,int y)
{
	int cnt=0;
	for (int i=0;i<4;++i)
	{
		int xx=x+dx[i],yy=y+dy[i];
		if (check(xx,yy) && c[xx][yy]=='.') ++cnt;
	}
	G[x][y]=cnt;
}
inline bool topsort()
{
	queue<pair<int,int> >q;
	int cnt=0;
	for (int i=0;i<tot;++i)
	{
		int x=a[i].x,y=a[i].y;
		if (G[x][y]==1)
		{
			q.push(pair<int,int> (x,y));
			G[x][y]=0;
		}
	}
	pair<int,int>m;
	while (!q.empty())
	{
		m=q.front();
		q.pop();
		int x=m.first,y=m.second;
		--G[x][y];
		for (int i=0;i<4;++i)
		{
			int xx=x+dx[i],yy=y+dy[i];
			if (check(xx,yy) && c[xx][yy]=='.')
			{
				G[xx][yy]=0;
				c[xx][yy]=ch[i];
				c[x][y]=str[i];
				for (int j=0;j<4;++j)
				{
					int xxx=xx+dx[j],yyy=yy+dy[j];
					if (check(xxx,yyy) && c[xxx][yyy]=='.')
					{
						dfs(xxx,yyy);
						if (G[xxx][yyy]==1)
							q.push(pair<int,int> (xxx,yyy));
					}
				}
				cnt+=2;
			}
		}
	}
	return cnt==tot;
}
int main()
{
	read(m);read(n);tot=0;
	for (int i=1;i<=m;++i)
	{
		scanf("%s",c[i]+1);
		for (int j=1;j<=n;++j)
			if (c[i][j]=='.')
			{
				a[tot].x=i,a[tot++].y=j;
				G[i][j]=0;
				if (check(i-1,j) && c[i-1][j]=='.')
					++G[i-1][j],++G[i][j];
				if (check(i,j-1) && c[i][j-1]=='.')
					++G[i][j-1],++G[i][j];
			}
	}
	if (topsort())
		for (int i=1;i<=m;++i)
			printf("%s\n",c[i]+1);
	else
		puts("Not unique");
	return 0;
}

D. POJ 3169 Layout

题目

POJ 3169

代码

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
inline int read()
{
	int f=1,num=0;
	char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar();	}
	while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
	return num*f;
}

int ver[maxn*2],edge[maxn*2],Next[maxn*2],head[maxn],len=0;
inline void add(int x,int y,int z)
{
	ver[++len]=y,edge[len]=z,Next[len]=head[x],head[x]=len;
}

int dist[maxn],cnt[maxn];
bool v[maxn];
queue<int>q;
int spfa(int s,int n)
{
	for (int i=0;i<maxn;++i) dist[i]=inf;
	memset(cnt,0,sizeof(cnt));
	memset(v,0,sizeof(v));
	++cnt[s];
	dist[s]=0;
	v[s]=1;
	q.push(s);
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		v[x]=0;
		for (int i=head[x];i;i=Next[i])
		{
			int y=ver[i],z=edge[i];
			if (dist[y]>dist[x]+z)
			{
				dist[y]=dist[x]+z;
				if (!v[y])
				{
					v[y]=1,q.push(y);
					++cnt[y];
					if (cnt[y]>n) return -1;//存在负环 
				}
			}
		}
	}
	if (dist[n]==inf) return -2;
	return dist[n]; 
}

int main()
{
	int n=read(),x=read(),y=read();
	for (int i=1;i<n;++i)
		add(i+1,i,0);
	for (int i=1;i<=x;++i)
	{
		int a=read(),b=read(),d=read();
		add(a,b,d);
	}
	for (int i=1;i<=y;++i)
	{
		int a=read(),b=read(),d=read();
		add(b,a,-d);
	}
	printf("%d\n",spfa(1,n));
	return 0;
}

E. POJ 2983 Is the Information Reliable?

题目

POJ 2983

代码

F. HDU 3440 House Man

题目

HDU 3440

代码

G.POJ 1275 Cashier Employment

题目

POJ 1275

代码

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/87005491