POJ2531 Network Saboteur DFS 或 无向图的最大割

来源:互联网 发布:apache 域名配置 编辑:程序博客网 时间:2024/06/05 17:57

题目大意:给你一个无向完全图,让你求出该图的最大割。


分析:裸的最大割问题,随机算法就行,卡好时间。


实现代码如下:

#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;int maze[25][25];int main(){    int n;    while(scanf("%d",&n)!=-1)    {        for(int i=1;i<=n;i++)          for(int j=1;j<=n;j++)            scanf("%d",&maze[i][j]);        bool vis[25]={0};//用0和1表示图中的顶点在哪个集合中        int time=2000*100;//随机次数要尽量大        long long ans=0;//纪录结果        long long cnt=0;//纪录当前最大值        while(time--)        {            int x=rand()%n+1;//生成随机数            vis[x]=!vis[x];//改变x所在的集合            for(int i=1;i<=n;i++)//枚举和x相连的每一个顶点            {                if(vis[x]!=vis[i])//如果i和x不在同一个集合中,就把权值加到cnt上                  cnt+=maze[x][i];                else if(x!=i)//i和x改变集合之前在一个集合中,那么减去由于x改变而多增加的这些权值                  cnt-=maze[x][i];            }            if(ans<cnt) ans=cnt;        }        printf("%lld\n",ans);    }    return 0;}



这道题也可以用深搜来做,从第一个点开始枚举,每个点都有两种状态(代表属于两个集合),然后分别回溯。


实现代码如下:

#include <cstdio>#include <iostream>using namespace std;int maze[25][25];int n,ans;bool s[25];void dfs(int cnt,int sum){    if(cnt>n)    {        if(ans<sum) ans=sum;        return ;    }    int m;    m=0;    s[cnt]=1;    for(int i=1;i<=cnt;i++)      if(!s[i]) m+=maze[cnt][i];    dfs(cnt+1,sum+m);    m=0;    s[cnt]=0;    for(int i=1;i<=cnt;i++)      if(s[i]) m+=maze[cnt][i];    dfs(cnt+1,sum+m);}int main(){    while(scanf("%d",&n)!=-1)    {        for(int i=1;i<=n;i++)          for(int j=1;j<=n;j++)            scanf("%d",&maze[i][j]);        ans=0;        dfs(1,0);        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击