hdu 3061 hdu 3996 最大权闭合图 最后一斩

hdu 3061 Battle :一看就是明显的最大权闭合图了,水提。。。。。。SB题也不说边数多少。。。。因为开始时候数组开小了,WA。。。。后来一气之下,开到100W,A了。。

hdu3996.  gold mine。。看了一下,简单题,几乎裸,不敲了。。

#include<iostream>//Battle
#include<queue>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=1000,maxe=1000000;
int nume=0;int head[maxv];int e[maxe][3];
void inline adde(int i,int j,int c)
{
    e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
    e[nume++][2]=c;
    e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
    e[nume++][2]=0;
}
int ss,tt,n,m;
int vis[maxv];int lev[maxv];
bool bfs()
{
    for(int i=0;i<maxv;i++)
      vis[i]=lev[i]=0;
    queue<int>q;
    q.push(ss);
    vis[ss]=1;
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        for(int i=head[cur];i!=-1;i=e[i][1])
        {
            int v=e[i][0];
            if(!vis[v]&&e[i][2]>0)
            {
                lev[v]=lev[cur]+1;
                vis[v]=1;
                q.push(v);
            }
        }
    }
    return vis[tt];
}
int dfs(int u,int minf)
{
    if(u==tt||minf==0)return minf;
    int sumf=0,f;
    for(int i=head[u];i!=-1&&minf;i=e[i][1])
    {
        int v=e[i][0];
        if(lev[v]==lev[u]+1&&e[i][2]>0)
        {
            f=dfs(v,minf<e[i][2]?minf:e[i][2]);
            e[i][2]-=f;e[i^1][2]+=f;
            sumf+=f;minf-=f;
        }
    }
    if(!sumf) lev[u]=-1;
    return sumf;
}
int dinic()
{
    int sum=0;
    while(bfs())sum+=dfs(ss,inf);
    return sum;
};

int cpy[maxv];int sumz=0;
void read_build()
{
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&cpy[i]);
        if(cpy[i]<0)
         adde(i,tt,-cpy[i]);
        else
         {
             adde(ss,i,cpy[i]);
              sumz+=cpy[i];
         }
    }
    int aa,bb;
    for(int i=0;i<m;i++)
     {
        scanf("%d%d",&aa,&bb);
        adde(aa,bb,inf);
     }
  /*  for(int i=1;i<=m+2;i++)
      for(int j=head[i];j!=-1;j=e[j][1])
      {
           if(j%2==0)
          printf("%d->%d:%d\n",i,e[j][0],e[j][2]);
      }*/
}
void init()
{
    nume=0;sumz=0;
    ss=n+1;tt=ss+1;
    for(int i=0;i<maxv;i++)
      {
       head[i]=-1;
      }
}
int main()
{
      while(~scanf("%d%d",&n,&m))
     {
         init();
        read_build();
       int ans;
       ans=sumz-dinic();
      printf("%d\n",ans);
    }
    return 0;
}

hdu 3061 hdu 3996 最大权闭合图 最后一斩,布布扣,bubuko.com

时间: 2025-01-02 09:16:16

hdu 3061 hdu 3996 最大权闭合图 最后一斩的相关文章

HDU 3879 Base Station 最大权闭合图

题目链接:点击打开链接 题意: 给定n个带权点m条无向带权边 选一个子图,则这个子图的权值为 边权和-点权和 求一个最大的权值 把边也当成点.然后是最大权闭合图 dinic: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; //点标 从0开始 F.Init(n) n=最大点标+10 const int N =

hdu 3917 Road constructions 最大权闭合图

Road constructions Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1470    Accepted Submission(s): 485 Problem Description N cities are required to connect with each other by a new transportatio

hdu 5772 String problem(最大权闭合图)

题目链接:hdu 5772 String problem 题意: 给你一个字符串,只含有数字. 你需要选择出一个子序列,使得这个子序列的权值最大. 这个子序列如果这个数字第一次出现就ans-=bx,否则就-=ax 然后如果第i个字符和第j个字符都在子序列里面,那么ans+=w[i][j] 问你最大ans是多少 官方题解: 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace

HDU 3061:Battle(最大权闭合图)

http://acm.hdu.edu.cn/showproblem.php?pid=3061 题意:中文题意. 思路:和上一题神似啊,比上一题还简单,重新看了遍论文让我对这个理解更加深了. 闭合图:如果某个点在图中的话,那么这个点的后继点全部都要在图中. 对应至题目,这里的必须攻占b以后才能攻占a,那么是a依赖于b.如果a在图中的话,那么b必定在图中(因为a是依赖于b的),所以是a连向b(而不是b连向a). 这里总结一下做最大权闭合图的套路:把权值为正的点与超级源点S相连,容量为该权值,把权值为

HDU 3061 Battle(最小割----最大权闭合图)

题目地址:HDU 3061 多校中遇到的最小割的最大权闭合模型花了一上午时间终于看懂啦. 最大权闭合图就是将一些互相有依赖关系的点转换成图,闭合图指的是在图中的每一个点的后继点都是在图内的. 还要明白简单割的概念,就是指所有的割边都与源点或汇点相连.然后让源点与正权点相连,汇点与负权点相连,权值均为其绝对值,有依赖关系的点连一条有向边,如果a必须在b的基础上,那么就连一条a->b的有向边,权值为INF.最后用所有正权值得和减去最小割的值就是答案. 具体证明可看胡伯涛大牛的国家队集训论文<最小割

HDU 3879:Base Station(最大权闭合图)

http://acm.hdu.edu.cn/showproblem.php?pid=3879 http://www.lydsy.com/JudgeOnline/problem.php?id=1497 题意:给出n个点m条边,其中每个点有一个权值代表修建这个点需要耗费的钱,然后m条边里面,代表如果两个修建好的点相连的话,那么可以得到一点利润.求最大的获利. 思路:和BZOJ 1497是同一道题目.学习最大权闭合图的题目,看了一下不清楚应该怎么建图,然后只好搜一个论文来看看.http://wenku

HDU 4971 A simple brute force problem.(最小割,最大权闭合图)

http://acm.hdu.edu.cn/showproblem.php?pid=4971 A simple brute force problem. Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 182    Accepted Submission(s): 115 Problem Description There's a com

hdu 3879 hdu 3917 构造最大权闭合图 俩经典题

hdu3879  base station : 各一个无向图,点的权是负的,边的权是正的.自己建一个子图,使得获利最大. 一看,就感觉按最大密度子图的构想:选了边那么连接的俩端点必需选,于是就以边做点,轻轻松松构造了最大权闭合图.简单题.分分钟搞定. hdu3917 :road  constructions :这题题目看了半天没理解...感觉描述的不好...一个有向图,每条路有响应公司承保,若选了该公司,那么该公司的路必需全部选,还有,该公司的承保的路的下面的一条路对应公司也要选,求最大获利.构

HDU 4971 A simple brute force problem. 强连通缩点+最大权闭合图

题意: 给定n个项目,m个技术难题 下面一行n个数字表示每个项目的收益 下面一行m个数字表示攻克每个技术难题的花费 下面n行第i行表示 第一个数字u表示完成 i 项目需要解决几个技术难题,后面u个数字表示需要解决的问题标号. 下面m*m的矩阵 (i,j) = 1 表示要解决j问题必须先解决i问题. (若几个问题成环,则需要一起解决) 问:最大收益. 思路: 先给问题缩点一下,每个缩点后的点权就是这个点内所有点权和. 然后跑一个最大权闭合图. #include<stdio.h> #include