【SDOI2013】【BZOJ3197】assassin
2016-02-17 14:57
387 查看
Description
Input
Output
Sample Input
4
1 2
2 3
3 4
0 0 1 1
1 0 0 0
Sample Output
1
HINT
暑假时候高大哥出来考试的题
丢题解跑
gty大哥的题解
Input
Output
Sample Input
4
1 2
2 3
3 4
0 0 1 1
1 0 0 0
Sample Output
1
HINT
暑假时候高大哥出来考试的题
丢题解跑
gty大哥的题解
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #define MAXN 710 #define GET (ch>='0'&&ch<='9') #define ULL unsigned long long #define base 43 using namespace std; int n,top,root; int S=0,T=29; int a[MAXN],b[MAXN]; int fa[MAXN],size[MAXN],deep[MAXN],g[2]; int f[MAXN][MAXN]; ULL hash[MAXN]; struct edge { int to; edge *next,*rev; }e[MAXN<<1],*prev[MAXN]; struct node { int deep,id; ULL hash; bool operator <(const node& a)const { return deep==a.deep?hash<a.hash:deep>a.deep; } bool operator ==(const node& a)const { return deep==a.deep&&hash==a.hash; } }s[MAXN]; void insert(int u,int v) { e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top]; } void in(int &x) { char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar(); } void dfs1(int x,int f)//Find G { size[x]=1;fa[x]=f;bool flag=1; for (edge *i=prev[x];i;i=i->next) if (i->to!=f) { dfs1(i->to,x);size[x]+=size[i->to]; if (size[i->to]>n>>1) flag=0; } if (n-size[x]>n>>1) flag=0; if (flag) for (int i=0;i<=1;i++) if (!g[i]) { g[i]=x;break; } } void dfs2(int x,int f)//Get Hash { deep[x]=deep[f]+1;int Top=0;ULL sta[MAXN];fa[x]=f; for (edge *i=prev[x];i;i=i->next) if (i->to!=f) dfs2(i->to,x); for (edge *i=prev[x];i;i=i->next) if (i->to!=f) sta[++Top]=hash[i->to]; sort(sta+1,sta+Top+1);hash[x]=41; for (int i=1;i<=Top;i++) (((hash[x]*=base)^=sta[i])+=sta[i])^=sta[i]; } int tp,ret; struct Edge { int from,to,c,w; Edge *next,*rev; }E[10010],*Prev[32],*from[32]; void Insert(int u,int v,int f,int w) { E[++tp].to=v;E[tp].from=u;E[tp].next=Prev[u];Prev[u]=&E[tp];E[tp].c=f;E[tp].w=w; } void add(int u,int v,int f,int w) { Insert(u,v,f,w);Insert(v,u,0,-w);E[tp].rev=&E[tp-1];E[tp-1].rev=&E[tp]; } bool cmp(int a,int b) { return hash[a]<hash[b]; } int spfa() { bool vis[32];memset(vis,0,sizeof(vis)); int dis[32];memset(dis,0x3f,sizeof(dis)); vis[S]=1;dis[S]=0;queue<int> q;q.push(S); while (!q.empty()) { int x=q.front();q.pop();vis[x]=0; for (Edge *i=Prev[x];i;i=i->next) if (i->c>0&&dis[i->to]>dis[x]+i->w) { dis[i->to]=dis[x]+i->w;from[i->to]=i; if (!vis[i->to]) vis[i->to]=1,q.push(i->to); } } return dis[T]!=0x3f3f3f3f; } void dfs() { int minn=0x3f3f3f3f; for (Edge *i=from[T];i;i=from[i->from]) minn=min(minn,i->c); for (Edge *i=from[T];i;i=from[i->from]) ret+=minn*i->w,i->c-=minn,i->rev->c+=minn; } int calc(int x,int y) { int sta1[MAXN],sta2[MAXN],tp1=0,tp2=0,i=0,j=0; for (edge *i=prev[x];i;i=i->next) if (i->to!=fa[x]) sta1[++tp1]=i->to; for (edge *i=prev[y];i;i=i->next) if (i->to!=fa[y]) sta2[++tp2]=i->to; sort(sta1+1,sta1+tp1+1,cmp);sort(sta2+1,sta2+tp2+1,cmp); memset(Prev,0,sizeof(Prev));memset(E,0,sizeof(Edge)*(tp+3));tp=0;ret=0; for (i=1;i<=tp1;i=j) { for (j=i+1;j<=tp1&&hash[sta1[i]]==hash[sta1[j]];j++); for (int k=i;k<j;k++) for (int l=i;l<j;l++) add(k,tp1+l,1,f[sta1[k]][sta2[l]]); } for (int i=1;i<=tp1;i++) add(S,i,1,0),add(i+tp1,T,1,0); while (spfa()) dfs(); return ret+(a[x]^b[y]); } int main() { in(n);int u,v,r=0; for (int i=1;i<n;i++) in(u),in(v),insert(u,v),insert(v,u),e[top].rev=&e[top-1],e[top-1].rev=&e[top]; for (int i=1;i<=n;i++) in(a[i]); for (int i=1;i<=n;i++) in(b[i]); dfs1(1,0); if (g[1]) { root=++n; for (edge *i=prev[g[0]];i;i=i->next) if (i->to==g[1]) { i->to=i->rev->to=n;break; } insert(n,g[0]);insert(n,g[1]); } else root=g[0]; dfs2(root,0); for (int i=1;i<=n;i++) s[i]=(node){deep[i],i,hash[i]}; sort(s+1,s+n+1); for (int l=1;l<=n;l=r) { for (r=l+1;r<=n&&s[l]==s[r];r++); for (int x=l;x<r;x++) for (int y=l;y<r;y++) f[s[x].id][s[y].id]=calc(s[x].id,s[y].id); } cout<<f[root][root]; }
相关文章推荐
- c语言实现hashmap(转载)
- Ruby中Hash的11个问题解答
- Ruby简明教程之数组和Hash介绍
- 在C#中生成与PHP一样的MD5 Hash Code的方法
- js中hash和ico的关联分析
- Javascript SHA-1:Secure Hash Algorithm
- 理解php Hash函数,增强密码安全
- PHP利用hash冲突漏洞进行DDoS攻击的方法分析
- PowerShell中定义哈希散列(Hash)和调用例子
- Redis String 类型和 Hash 类型学习笔记与总结
- php操作redis中的hash和zset类型数据的方法和代码例子
- Perl 哈希Hash用法之入门教程
- perl哈希hash的常见用法介绍
- php自定义hash函数实例
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- php对文件进行hash运算的方法
- php常用hash加密函数
- PHP Hash算法:Times33算法代码实例
- php的hash算法介绍