1499 图

来源:互联网 发布:淘宝网天猫商城女装 编辑:程序博客网 时间:2024/06/07 07:20

1499 图

Description

给一个无向图,你要将这些点分成A、B两个集合,使得满足A的导出子图是一个完全图,而B的导出子图是一个没有边的图。

但是事实上你不一定能够做到,所以你允许有错误。我们定义一个完美值为:

1.如果A中两点有边相连,则增加|i-j|的完美值。
2.如果B中两点无边相连,则增加|i-j|的完美值。
(i,j是这两个点的编号)

那么,我们让完美值最大就可以了。

N <= 1000, M <= 200000

Input

N, M 表示点数和边数

M行,

u,v表示一条无向边。

(不会有重边和自环)

Output

一个数,表示最大的完美值。

Input 示例

5 5
1 2
1 3
1 4
1 5
2 3

Output 示例

11

Solution

一道最小割的题目,但下面这种神奇的方法竟然过了。。。(虽然后期重测WA了一个,要看正解请跳过下一段代码)

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int n,m,ans,map[1005][1005];int Abs(int x){    if (x<0) return -x;    return x;}int read(){    int ans=0;    char ch=getchar();    while (ch<'0' || ch>'9') ch=getchar();    while (ch>='0' && ch<='9'){        ans=ans*10+ch-'0';        ch=getchar();    }    return ans;}int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=m;i++){        int x=read(),y=read();        ans+=Abs(x-y);        map[x][y]=map[y][x]=1;    }    int x=0;    for (int i=1;i<=n;i++)        for (int j=i+1;j<=n;j++)            x+=j-i;    ans=max(ans,x-ans);    printf("%d\n",ans);}/*这段是正解(妥妥的最小割)*/#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define N 5000005#define INF 0x3f3f3f3fusing namespace std;int st,ed,head[N],next[N],dis[N],son[N],q[N],/*p[200000],*/h[N],cnt;bool vis[N];int n,m,f[1010][1010],s[1010],t[1010];int Abs(int x){    if (x<0) return -x;    return x;}void addedge(int u,int v,int l){    next[++cnt]=head[u];son[cnt]=v;dis[cnt]=l;head[u]=cnt;    next[++cnt]=head[v];son[cnt]=u;dis[cnt]=0;head[v]=cnt;    //p[cnt-1]=cnt;p[cnt]=cnt-1;}bool bfs(){    memset(h,0,sizeof(h));    memset(vis,false,sizeof(vis));    int hd=0,tl=1;q[1]=st;vis[st]=true;    while (hd<tl){        int u=q[++hd];        int k=head[u];        while (k!=0){            int v=son[k];            if ((not vis[v])&&(dis[k]>0)){                q[++tl]=v;                h[v]=h[u]+1;                vis[v]=true;            }            k=next[k];        }    }    if (h[ed]==0) return false; else return true;}int dfs(int u,int lim){    if (u==ed) return lim;    int k=head[u],l=0;    while (k!=0){        int v=son[k];        if (h[v]==h[u]+1){            int d=dfs(v,min(lim-l,dis[k]));            dis[k]-=d;            dis[k^1]+=d;            l+=d;            if (l==lim) break;        }        k=next[k];    }    return l;}int dinic(){    int ans=0;    while (bfs()){        ans+=dfs(st,INF);    }    return ans;}int main(){    scanf("%d%d",&n,&m);    cnt=1;    for (int i=1;i<=m;i++){        int u,v;        scanf("%d%d",&u,&v);        f[u][v]=f[v][u]=1;    }    for (int i=1;i<=n;i++)        for (int j=i+1;j<=n;j++)            if (!f[i][j]){                t[i]+=Abs(i-j);t[j]+=Abs(i-j);                addedge(i,j,Abs(i-j));                addedge(j,i,Abs(i-j));            }            else{                s[i]+=Abs(i-j);s[j]+=Abs(i-j);                addedge(i,j,Abs(i-j));                addedge(j,i,Abs(i-j));            }    st=0;ed=n+1;    int delta=0;    for (int i=1;i<=n;i++){        addedge(st,i,s[i]);        addedge(i,ed,t[i]);    }    int ans=dinic();    for (int i=1;i<=n;i++)        for (int j=i+1;j<=n;j++)            delta+=Abs(i-j);    printf("%d\n",delta-ans/2);    return 0;}
原创粉丝点击