HDU 3526 最小割

点击打开链接

题意:有两个公司分别提供的n个部件,每个部件的价格给出,现在要这买n个部件,我可以选择两个公司中的任意一个,但是对于下面给的m个关系来说,若满足i与j不再同一个公司,那么就要加上c的费用,问买n个部件的最小花费

思路:刚刚读完题的时候感觉像是最小费用流呐,流量就是5呗,然后根据关系建图,画了一会也画不出来,看了一下正解竟然是最小割,思想到时很简单,但是思路不对的话还是很难想到的,建图就是源点,中间一列n个部件,然后汇点,源点连中间的话就是A公司的n个物品,然后中间连汇点的话就是B公司的n个物品的价格,中间的有关系的点互相连接,那么如果全部选择A公司的,最小割就是结果,全部选择B公司的最小割也是结果,而如果有不全在一个公司的话,对于题意来说若B公司的3号物品与A公司的物品有冲突,那么就加上这个值,在最小割中就是把这条边割下去使得图不连通的,一会继续想一下费用流

#include <queue>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=1010;
struct edge{
    int to,cap,rev;
    edge(int a,int b,int c){to=a;cap=b;rev=c;}
};
vector<edge>G[maxn];
int level[maxn],iter[maxn];
void add_edge(int from,int to,int cap){
    G[from].push_back(edge(to,cap,G[to].size()));
    G[to].push_back(edge(from,0,G[from].size()-1));
}
void bfs(int s){
    memset(level,-1,sizeof(level));
    queue<int>que;level[s]=0;
    que.push(s);
    while(!que.empty()){
        int v=que.front();que.pop();
        for(unsigned int i=0;i<G[v].size();i++){
            edge &e=G[v][i];
            if(e.cap>0&&level[e.to]<0){
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
}
int dfs(int v,int t,int f){
    if(v==t) return f;
    for(int &i=iter[v];i<G[v].size();i++){
        edge &e=G[v][i];
        if(e.cap>0&&level[v]<level[e.to]){
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
int max_flow(int s,int t){
    int flow=0;
    while(1){
        bfs(s);
        if(level[t]<0) return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,inf))>0) flow+=f;
    }
}
int main(){
    int n,m,cost,u,v;
    while(scanf("%d%d",&n,&m)!=-1){
        for(int i=0;i<maxn;i++) G[i].clear();
        for(int i=1;i<=n;i++){
            scanf("%d",&u);
            add_edge(0,i,u);
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&u);
            add_edge(i,n+1,u);
        }
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&cost);
            add_edge(u,v,cost);
            add_edge(v,u,cost);
        }
        int ans=max_flow(0,n+1);
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-14 17:10:24

HDU 3526 最小割的相关文章

hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割

题意:方格取数,如果取了相邻的数,那么要付出一定代价.(代价为2*(X&Y))(开始用费用流,敲升级版3820,跪...) 建图:  对于相邻问题,经典方法:奇偶建立二分图.对于相邻两点连边2*(X&Y),源->X连边,Y->汇连边,权值w为点权. ans=总点权-最小割:如果割边是源->X,表示x不要选(是割边,必然价值在路径上最小),若割边是Y-汇点,同理:若割边是X->Y,则表示选Y点且选X点, 割为w( 2*(X&Y) ). 自己的确还没有理解其本质

There is a war (hdu 2435 最小割+枚举)

There is a war Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 970    Accepted Submission(s): 277 Problem Description There is a sea. There are N islands in the sea. There are some directional

hdu 3204(最小割--关键割边)

Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7491   Accepted: 2172 Description Ikki is the king of a small country – Phoenix, Phoenix is so small that there is only one city that is responsible fo

hdu 5076 最小割灵活的运用

题意比较复杂,其实关键是抽象出来:每个点,可以赋予俩个值(二选一,必需选一个,设ai,bi).  求所有之和最大,有条件:若俩个点同时满足: 1,:点的二进制只有一位不同.  2:至少有一个是选B值: 则可获得对应加成. 这题开始想了半天,建图遇到问题,看了官方说是最小割,于是入手: a值就是小于阈值的最大值,B值就是大于等于的最大值. 思路:俩个点选其一,必然想到建二分(每个点一分为二)图,中间连无穷的边.因为只有一位不同,必然分奇偶点,有奇数个1的点,源点到他为A值,对应点到汇点为B值,偶点

hdu 1565 最小割

黑白染色,源指向白,黑指向汇,容量都是方格中数的大小,相邻的格子白指向黑,容量为oo,然后求一次最小割. 这个割是一个简单割,如果只选择不在割中的点,那么一种割就和一个选数方案一一对应,割的大小就是不选的那些数的大小,我们需要最小化这个值. 答案=总和-最小割 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 #define maxn 410 6

Being a Hero (hdu 3251 最小割 好题)

Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1211    Accepted Submission(s): 381 Special Judge Problem Description You are the hero who saved your country. As promised, the ki

hdu 1569 最小割

和HDU 1565是一道题,只是数据加强了,貌似轮廓线DP来不了了. 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 #define maxn 2510 6 #define oo 0x3f3f3f3f 7 using namespace std; 8 9 struct Edge { 10 int u, v, f; 11 Edge( int u,

hdu 3046 最小割

每个栅栏其实就是一条边,修一些栅栏,使得狼不能抓到羊,其实就是求一个割,使得羊全在S中,狼全在T中. 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <queue> 5 #define maxn 40010 6 #define oo 0x3f3f3f3f 7 #define clr(arr,n) memset(&arr,0,sizeof(arr[0])*(

Pleasant sheep and big big wolf (hdu 3046 最小割)

Pleasant sheep and big big wolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2371    Accepted Submission(s): 988 Problem Description In ZJNU, there is a well-known prairie. And it attracts p