3714: [PA2014]Kuglarz

来源:互联网 发布:怎么做白羊座红颜知已 编辑:程序博客网 时间:2024/05/18 11:25

题目链接

题目大意:一个01序列,花费cij可以知道sum(i,j)的奇偶性
求最少花费多少钱可以还原这个序列

题解:把前缀和数组当作点
知道sum(i,j)的奇偶性=知道sum[j]-sum[i-1]的奇偶性
还原序列=知道所有sum[]的奇偶性
发现这个东西是可以互推的,所以把所有点联通就可以了

(i1,j)cij

我的收获:神奇建模……区间和转前缀和端点

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int M=2005;#define rep(i,x,y) for(int i=x;i<=y;i++)int n,t,z,cnt;int f[M];long long ans;struct edge{int u,v,val;}e[M*M];bool operator <(edge a,edge b){return a.val<b.val;}void add(int x,int y,int z){e[++t].u=x,e[t].v=y,e[t].val=z;}int find(int x){return f[x]==x?x:f[x]=find(f[x]);}void uniom(int x,int y,int z){    x=find(x),y=find(y);    if(x!=y) f[x]=y,ans+=z,cnt++;}void kruskal(){    sort(e+1,e+1+t);    rep(i,1,n) f[i]=i;    rep(i,1,t){        uniom(e[i].u,e[i].v,e[i].val);        if(cnt==n) break;    }}void work(){    kruskal();    cout<<ans<<endl;}void init(){    cin>>n;    rep(i,1,n) rep(j,i,n) cin>>z,add(i-1,j,z);}int main(){    init();    work();    return 0;}
原创粉丝点击