常规操作:
Description:
判断 n个单词是 否可以相连成一条链,两的件个单词是 否可以相连成一条链,两的件个单词是 否可以相连成一条链,两的件前一个单 词的最后字母和词。
Solution:
Code:
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define Sz(a)sizeof(a)
#define mcl(a,b)memset(a,b,Sz(a))
#define mcp(a,b)memcpy(a,b,Sz(b))
#define pb push_back
#define fi first
#define se second
template<class T>inline bool chkmin(T&x,T y){return y1 :0;}
template<class T>inline bool chkmax(T&x,T y){return x1:0;}
inline LL Max(LL x,LL y){return x>y?x:y;}
inline LL Min(LL x,LL y){return xtypedef pair<int,int>PII;
#define N 30
int n;
char s[1002];
int In[N],Out[N],fa[N];
int find(int x){return x==fa[x]?x:find(fa[x]);}
void Clear(){
mcl(In,0);
mcl(Out,0);
SREP(i,1,N)fa[i]=i;
}
int main(){
int cas;scanf("%d",&cas);
while(cas--){
Clear();
scanf("%d",&n);
REP(i,1,n){
scanf("%s",s);
int len=strlen(s);
int x=s[0]-'a'+1;
int y=s[len-1]-'a'+1;
Out[x]++;
In[y]++;
x=find(x),y=find(y);
if(x!=y)fa[y]=x;
}
bool f=1;
int innum=0,outnum=0,root=0;
SREP(i,1,N){
if(!In[i] && !Out[i])continue;
if(fa[i]==i){
root++;
if(root>1){f=0;break;}
}
if(In[i]!=Out[i]){
if(In[i]-Out[i]==1)innum++;
else if(Out[i]-In[i]==1)outnum++;
else {f=0;break;}
}
}
if(f && ((!innum && !outnum) || (innum==1 && outnum==1)))puts("Ordering is possible.");
else puts("The door cannot be opened.");
}
return 0;
}
Description:
给出一张无向图,求最少几笔能画完这张图。
首先,我们需要知道一些性质:
Prove:
Code:
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define Sz(a)sizeof(a)
#define mcl(a,b)memset(a,b,Sz(a))
#define mcp(a,b)memcpy(a,b,Sz(b))
#define pb push_back
#define fi first
#define se second
template<class T>inline bool chkmin(T&x,T y){return y1 :0;}
template<class T>inline bool chkmax(T&x,T y){return x1:0;}
inline LL Max(LL x,LL y){return x>y?x:y;}
inline LL Min(LL x,LL y){return xtypedef pair<int,int>PII;
#define N 100002
/*
此题我们可以知道一些性质:
1.孤立点 -> 0 画
2.(半)欧拉图 -> 1 画
3.非(半)欧拉图 -> 奇数度的点个数/2 画
*/
int n,m;
int fa[N];
int degree[N];
int sum[N],cnt[N];
// sum[i]表示该联通量的点数
// cnt[i]表示该联通量的奇数度点数
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void Clear(){
mcl(degree,0);
mcl(sum,0);
mcl(cnt,0);
REP(i,1,n)fa[i]=i;
}
int main(){
while(~scanf("%d%d",&n,&m)){
Clear();
REP(i,1,m){
int x,y;
scanf("%d%d",&x,&y);
degree[x]++,degree[y]++;
x=find(x),y=find(y);
if(x!=y)fa[x]=y;
}
REP(i,1,n){
int root=find(i);
sum[root]++;
cnt[root]+=(degree[i]&1);
}
int ans=0;
REP(i,1,n){
if(sum[i]<2)continue;
ans+=(!cnt[i])?1:(cnt[i]>>1);
}
printf("%d\n",ans);
}
return 0;
}
Description:
给一个无向图,让你指定边的方向,比如 a→b 为 1,a←b 为 0,在给所有边指定方向后,对无向图上的每个点,如果满足|出度-入度|<2,那么输出任意一种方案。
Solution:
Code:
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define Sz(a)sizeof(a)
#define mcl(a,b)memset(a,b,Sz(a))
#define mcp(a,b)memcpy(a,b,Sz(b))
#define pb push_back
#define fi first
#define se second
template<class T>inline bool chkmin(T&x,T y){return y1 :0;}
template<class T>inline bool chkmax(T&x,T y){return x1:0;}
inline LL Max(LL x,LL y){return x>y?x:y;}
inline LL Min(LL x,LL y){return xtypedef pair<int,int>PII;
#define N 100002
#define M 300002
int n,m;
int qwq,head[N];
struct edge{
int to,next;
}E[M<<1];
void addedge(int x,int y){E[qwq]=(edge){y,head[x]};head[x]=qwq++;}
int degree[N],du[2][N];
bool vis[M<<1];
int ans[M];
void Clear(){
mcl(degree,0);
mcl(du,0);
mcl(vis,0);
qwq=0;
mcl(head,-1);
mcl(ans,-1);
}
void dfs(int x,int op){
for(int &i=head[x];~i;i=E[i].next)if(!vis[i]){
int y=E[i].to;
if(y!=x && du[op][y]1][y])continue;
vis[i]=vis[i^1]=1;
if(i&1)ans[i>>1]=op^1;
else ans[i>>1]=op;
du[op][x]++;
du[op^1][y]++;
dfs(y,op);
break;
}
}
int main(){
int cas;cin>>cas;
while(cas--){
scanf("%d%d",&n,&m);
Clear();
SREP(i,0,m){
int x,y;
scanf("%d%d",&x,&y);
degree[x]++,degree[y]++;
addedge(x,y),addedge(y,x);
}
REP(i,1,n) while(du[0][i]+du[1][i]0][i]<=du[1][i])?0:1);
SREP(i,0,m)printf("%d\n",ans[i]);
}
return 0;
}