第一眼想到tarjan,水了30分
有如下漏洞
30分代码
#include<cstdio> #include<cstring> using namespace std; const int maxn=(1e4)+5,maxE=(2e4)+5; const char ans[2][10]={{"NO"},{"YES"}}; int n,m,p[maxn],tot,lnk[maxn],nxt[maxE],son[maxE],T,vis[maxn]; char gt(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } int read(){ int ret=0;char ch=gt(); while(ch<'0'||ch>'9'){if(ch==EOF) return -1;ch=gt();} while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt(); return ret; } void add_e(int x,int y){son[++tot]=y,nxt[tot]=lnk[x],lnk[x]=tot;} bool DFS(int x){ for(int j=lnk[x];j;j=nxt[j])if(vis[son[j]]<T){ vis[son[j]]=T; if(!p[son[j]]||DFS(p[son[j]])){p[son[j]]=x;return 1;} } return 0; } bool check(){ memset(vis,0,sizeof vis),memset(p,0,sizeof p),T=1; for(int i=1;i<=n;i++,T++) if(!DFS(i)) return 0; return 1; } int main(){ for(n=read(),m=read();n>=0&&m>=0;n=read(),m=read()){ memset(lnk,0,sizeof lnk),tot=0; for(int i=1;i<=m;i++){ int x=read(),y=read(); add_e(x,y); } printf("%s\n",ans[check()]); } return 0; }
这题的正解是二分图最大匹配,emmm,确实有道理,这样就肯定能满足条件
1.dinic
#include<cstdio> #include<cctype> #include<cstring> #define maxn 10002 using namespace std; int n,m,head[maxn],tot,to[maxn<<1],nex[maxn<<1],p[maxn]; bool vis[maxn]; bool dfs(int x){ for(int i=head[x];i;i=nex[i]) if(!vis[to[i]]){ vis[to[i]]=1; if(!p[to[i]]||dfs(p[to[i]])){ p[to[i]]=x;return 1; } } return 0; } bool check(){ tot=1; for(int i=1;i<=n;i++,tot++){memset(vis,0,sizeof(vis));if(!dfs(i))return 0;} return 1; } int main(){ while(scanf("%d%d",&n,&m)==2){ memset(head,0,sizeof(head)); memset(p,0,sizeof(p)); for(int i=1;i<=m;i++){ int x,y;scanf("%d%d",&x,&y); to[i]=y;nex[i]=head[x];head[x]=i; } if(!check())printf("NO\n");else printf("YES\n"); } }