[BZOJ2730][HNOI2012]矿场搭建

来源:互联网 发布:支持mac的网游加速器 编辑:程序博客网 时间:2024/04/30 06:38

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2730

这题标准做法应该是tarjan求割点,但数据范围是在是有点水,暴力就好。(事实上在CodeVS上测tarjan做法反而比暴力慢。。。难道是初始化的问题?)

Tarjan

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int N=505,M=2600,inf=0x3fffffff;int head[N],ver[M<<1],e[M<<1],next[M<<1],fa[N];int col[N],dfn[N],low[N],bel[N],hav[N];bool cut[N],vis[N];int tot=1,t=0,n=0,m,ne=0,cnt=0,T=0;long long ans=1;inline int read () {    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9') { if (ch=='-')f=-1;ch=getchar(); }    while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();    return x*f;}void add (int u,int v) {    ver[++tot]=v;next[tot]=head[u];head[u]=tot;    ver[++tot]=u;next[tot]=head[v];head[v]=tot;}void Tarjan (int x,int dep) {    dfn[x]=++t;low[x]=t;    col[x]=-1;     int cnt=0;    for (int i=head[x];i;i=next[i]) {        fa[ver[i]]=x;        if (!col[ver[i]]) {            cnt++;            Tarjan(ver[i],dep+1);            low[x]=min(low[x],low[ver[i]]);            if (dep==1&&cnt>1) cut[x]=1;            if (dep>1&&low[ver[i]]>=dfn[x]) cut[x]=1;        }        else if (col[ver[i]]==-1&&ver[i]!=fa[x])             low[x]=min(low[x],dfn[ver[i]]);    }    col[x]=1;}void dfs (int x) {    vis[x]=1;    if (!bel[x]) bel[x]=ne; else bel[x]=-1;    for (int i=head[x];i;i=next[i])         if (!vis[ver[i]]&&!cut[ver[i]])            dfs(ver[i]);}int main () {    int u,v,w,tmp;    while (scanf("%d",&m)!=EOF) {        if (!m) return 0;        t=ne=cnt=n=0; ans=tot=1; //n=0        memset(cut,0,sizeof(cut));        memset(vis,0,sizeof(vis));        memset(col,0,sizeof(col));        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));        memset(bel,0,sizeof(bel));        memset(hav,0,sizeof(hav));        memset(head,0,sizeof(head));        memset(fa,0,sizeof(fa));        for (int i=1;i<=m;i++) {            u=read(); v=read();            n=max(n,u);n=max(n,v);            add(u,v);        }        for (int i=1;i<=n;i++)             if (col[i]==0) Tarjan(i,1);//        for (int i=1;i<=n;i++)             if (cut[i]) {                memset(vis,0,sizeof(vis));//                for (int j=head[i];j;j=next[j])                     if (!vis[ver[j]]&&!cut[ver[j]])                        { ++ne;dfs(ver[j]); }            }        for (int i=1;i<=n;i++)             if (bel[i]!=-1) ++hav[bel[i]];//        cnt=0;        for (int i=1;i<=ne;i++)             if (hav[i]) cnt++,ans*=hav[i];        printf("Case %d: ",++T);        if (!cnt) printf("2 %d\n",n*(n-1)/2);        else printf("%d %lld\n",cnt,ans);    }    return 0;}

暴力做法

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;typedef long long ll;ll ans;int T,n,m,cnt,tot,K;int t[505],id[505],head[505];bool cut[505],vis[505];struct data { int to,next,v; }e[1005];inline int read () {    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9') { if (ch=='-')f=-1;ch=getchar(); }    while (ch>='0'&&ch<='9') { x=x*10+ch-48;ch=getchar(); }    return x*f;}void add (int u,int v) {    e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;    e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt; }void dfs (int x) {    vis[x]=1;    for (int i=head[x];i;i=e[i].next)         if (!vis[e[i].to]&&e[i].to!=K) {            vis[e[i].to]=1;            dfs(e[i].to);        }}void dfs2 (int x) {    vis[x]=1;    if (!id[x]) id[x]=K;    else id[x]=-1;    for (int i=head[x];i;i=e[i].next)         if (!vis[e[i].to]&&!cut[e[i].to])            dfs2(e[i].to);}int main () {    while (scanf("%d",&m)!=EOF) {        if (m==0) return 0;        T++;printf("Case %d: ",T);        n=cnt=tot=0; ans=1;        memset(head,0,sizeof(head));        memset(cut,0,sizeof(cut));        memset(id,0,sizeof(id));        memset(t,0,sizeof(t));        for (int i=1;i<=m;i++) {            int u=read(),v=read();            n=max(u,n); n=max(v,n);            add(u,v);        }        for (K=1;K<=n;K++) {            memset(vis,0,sizeof(vis));            dfs(K%n+1);            for (int i=1;i<=n;i++)                 if (!vis[i]&&i!=K) {                    cut[K]=1;break;                }        }        K=0;        for (int x=1;x<=n;x++)             if (cut[x]) {                memset(vis,0,sizeof(vis));                for (int i=head[x];i;i=e[i].next)                     if (!vis[e[i].to]&&!cut[e[i].to]) {                        K++;dfs2(e[i].to);                    }            }        for (int i=1;i<=n;i++)             if (id[i]!=-1)                t[id[i]]++;        for (int i=1;i<=K;i++)             if (t[i]) tot++,ans*=t[i];        if (!tot) printf("2 %d\n",n*(n-1)/2);        else printf("%d %lld\n",tot,ans);    }    return 0;}
0 0
原创粉丝点击