[BZOJ4625][BeiJing2016]水晶 网络流

来源:互联网 发布:ubuntu安装jdk tar.gz 编辑:程序博客网 时间:2024/06/05 15:10

没时间了先溜了有时间补

/**************************************************************    Problem: 4625    User: di4CoveRy    Language: C++    Result: Accepted    Time:2368 ms    Memory:24052 kb****************************************************************/#include <iostream>#include <cstdio>#include <map>#include <algorithm>#include <vector>#include <cstring>#include <queue>#include <cassert>#define eps 1e-10#define sn 300000000#define INF 2147483647#define N 100050#define mp(x,y) make_pair(x,y)using namespace std;map< pair<int,int>,int >vis;map< pair<int,int>,int >val;const int fx[] = {0,1,1,0,-1,-1,0};const int fy[] = {-1,0,1,1,0,-1,-1};int n,x[N],y[N],z[N],cur[N],S,T,tot,ex[N],l[N],r[N];int ans,c[N],cut[N];struct Node {int u; int cap; int rec;};struct Edge{ int u,cap,next; }e[10*N];//vector<Node> e[N];int p[N],head[N],cnt=1;void add(int a,int b,int v) {    e[++cnt].u = b;    e[cnt].cap = v;    e[cnt].next = head[a];    head[a] = cnt;}void add_Node(int a,int b,int v){    add(a,b,v); add(b,a,0);    return ;//  Node tmp;//    tmp.u = b;//    tmp.cap = v;//    tmp.rec = e[b].size();//    e[a].push_back(tmp);////    tmp.u = a;//    tmp.cap = 0;//    tmp.rec = e[a].size() - 1;//    e[b].push_back(tmp);}bool BFS() {    bool flag = false;    memset(p,0,sizeof(p));    memset(cur,0,sizeof(cur));    queue<int> q;    q.push(S);    p[S] = 1;    while (!q.empty()) {        int u = q.front();q.pop();        if (u == T) flag = true;        for (int i=head[u];i;i=e[i].next) {            int v = e[i].u;            int cp = e[i].cap;            if (p[v] == 0 && cp > 0) {                q.push(v);                p[v] = p[u] + 1;            }        }    }    return flag;}int DFS(int u,int flow) {    if (u == T) return flow;    int g = 0 , f = flow;    for (int i=head[u];i;i=e[i].next) {        cur[u] = i;        int v = e[i].u;        int cp = e[i].cap;        int tmp = 0;        if (p[v] == p[u]+1 && cp > 0 && (tmp = DFS(v,min(f,cp))) > 0) {            g += tmp;            f -= tmp;            e[i].cap -= tmp;            e[i^1].cap += tmp;        }    }    return g;}int main() {    #ifndef ONLINE_JUDGE//      freopen("1.in","r",stdin);    #endif    scanf("%d",&n);    for (int i=1;i<=n;i++) {        int Z,C;        scanf("%d%d%d%d",&x[i],&y[i],&Z,&C);        x[i] -= Z , y[i] -= Z;        c[i] = (x[i]+y[i]) % 3 ? 10 * C : 11 * C;        ans += c[i];        if (!vis[ mp(x[i],y[i]) ])            vis[ mp(x[i],y[i]) ] = i , val[ mp(x[i],y[i]) ] = c[i];        else            val[ mp(x[i],y[i]) ] += c[i] , ex[i] = 1;    }    S = ++tot, T = ++tot;    for (int i=1;i<=n;i++) l[i] = ++tot , r[i] = ++tot;    for (int i=1;i<=n;i++) if (!ex[i] && (x[i]+y[i]+sn)%3 == 0)         add_Node(l[i],r[i],val[ mp(x[i],y[i]) ]);    for (int i=1;i<=n;i++) if (!ex[i] && (x[i]+y[i]+sn)%3 == 1) add_Node(S,r[i],val[ mp(x[i],y[i]) ]);    for (int i=1;i<=n;i++) if (!ex[i] && (x[i]+y[i]+sn)%3 == 2) add_Node(l[i],T,val[ mp(x[i],y[i]) ]);    for (int i=1;i<=n;i++) if (!ex[i]) {        for (int _=1;_<=6;_++) {            int xx = x[i] + fx[_] , yy = y[i] + fy[_] , pmt = vis[ mp(xx,yy) ];            if (!pmt) continue;            if ((xx+yy+sn) % 3 == 0 && (x[i]+y[i]+sn)%3 == 1) add_Node(r[i],l[pmt],INF);            if ((xx+yy+sn) % 3 == 2 && (x[i]+y[i]+sn)%3 == 0) add_Node(r[i],l[pmt],INF);        }    }    while (BFS()) ans -= DFS(S,INF);    printf("%d.%d\n",ans/10,ans%10);    return 0;}
0 0