bzoj 1539: [POI2005]Dwu-Double-row
2017-03-12 19:28
176 查看
假设一列交换表示为1,不换表示为0.
身高相同的两个人相当于给其中两列了一个限制条件,要么是两个必须相等,要么一个为零一个为一。
有了关系后我们就可以把每列当成一个点建边,边权为0表示必须相同,1为必须不同,这样每个联通块会被分为两个确定的集合,把$size$小的交换就行了。
身高相同的两个人相当于给其中两列了一个限制条件,要么是两个必须相等,要么一个为零一个为一。
有了关系后我们就可以把每列当成一个点建边,边权为0表示必须相同,1为必须不同,这样每个联通块会被分为两个确定的集合,把$size$小的交换就行了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 using namespace std; int n; int cnt[2]; int v ,vis ; int be ,pos ; int head ,ver ,nxt ,tot,quan ; void add(int a,int b,int c) { tot++;nxt[tot]=head[a];head[a]=tot;quan[tot]=c;ver[tot]=b;return ; } void dfs(int x,int b) { vis[x]=1;cnt[b]++; for(int i=head[x];i;i=nxt[i]) { if(!vis[ver[i]]) { dfs(ver[i],(b+quan[i])&1); } } return ; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int tmp; scanf("%d",&tmp); if(be[tmp]) { add(be[tmp],i,1); add(i,be[tmp],1); } else be[tmp]=i,pos[tmp]=1; } for(int i=1;i<=n;i++) { int tmp; scanf("%d",&tmp); if(be[tmp]) { if(pos[tmp]==1) { add(be[tmp],i,0); add(i,be[tmp],0); } else { add(be[tmp],i,1); add(i,be[tmp],1); } } else be[tmp]=i,pos[tmp]=2; } int ans=0; for(int i=1;i<=n;i++) { if(!vis[i]) { cnt[0]=cnt[1]=0; dfs(i,0); ans+=min(cnt[0],cnt[1]); } } printf("%d\n",ans); return 0; }
相关文章推荐
- BZOJ 1537: [POI2005]Aut- The Bus|动态规划|树状数组
- [BZOJ1528][POI2005]sam-Toy Cars(贪心)
- 【POI2005】【BZOJ1529】ska Piggy banks
- 【BZOJ】【1532】【POI2005】Kos-Dicing
- BZOJ1537: [POI2005]Aut- The Bus
- BZOJ 1529 POI2005 ska Piggy banks 并查集
- [BZOJ1531] [POI2005]Bank notes
- bzoj1532: [POI2005]Kos-Dicing
- bzoj1529 [POI2005]ska Piggy banks
- Taran 缩点【bzoj1529】[POI2005]ska Piggy banks
- bzoj1528 [POI2005]sam-Toy Cars
- 怎样获取DataGrid被双击的行 How to find DataGrid Double Clicked Row
- *****How to handle a double-click on a grid row or cell
- JZOJ 4675. 【NOIP2016提高A组模拟7.21】Double-row
- bzoj1531[POI2005]Bank notes 多重背包
- bzoj1529: [POI2005]ska Piggy banks(tarjan||并查集)
- 【BZOJ 1528】[POI2005]sam-Toy Cars 贪心+堆
- 【bzoj1528】 [POI2005]sam-Toy Cars
- BZOJ 1529: [POI2005]ska Piggy banks 并查集
- bzoj1537 [POI2005]Aut- The Bus