zoukankan      html  css  js  c++  java
  • Petya and Graph(最小割,最大权闭合子图)

    Petya and Graph

    http://codeforces.com/contest/1082/problem/G

    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Petya has a simple graph (that is, a graph without loops or multiple edges) consisting of nn vertices and mm edges.

    The weight of the ii-th vertex is aiai.

    The weight of the ii-th edge is wiwi.

    A subgraph of a graph is some set of the graph vertices and some set of the graph edges. The set of edges must meet the condition: both ends of each edge from the set must belong to the chosen set of vertices.

    The weight of a subgraph is the sum of the weights of its edges, minus the sum of the weights of its vertices. You need to find the maximum weight of subgraph of given graph. The given graph does not contain loops and multiple edges.

    Input

    The first line contains two numbers nn and mm (1n103,0m1031≤n≤103,0≤m≤103) - the number of vertices and edges in the graph, respectively.

    The next line contains nn integers a1,a2,,ana1,a2,…,an (1ai1091≤ai≤109) - the weights of the vertices of the graph.

    The following mm lines contain edges: the ii-e edge is defined by a triple of integers vi,ui,wivi,ui,wi (1vi,uin,1wi109,viui1≤vi,ui≤n,1≤wi≤109,vi≠ui). This triple means that between the vertices vivi and uiui there is an edge of weight wiwi. It is guaranteed that the graph does not contain loops and multiple edges.

    Output

    Print one integer — the maximum weight of the subgraph of the given graph.

    Examples
    input
    4 5
    1 5 2 2
    1 3 4
    1 4 4
    3 4 5
    3 2 2
    4 2 2
    
    output
    8
    
    input
    3 3
    9 7 8
    1 2 1
    2 3 2
    1 3 3
    
    output
    0
    
    Note

    In the first test example, the optimal subgraph consists of the vertices 1,3,41,3,4 and has weight 4+4+5(1+2+2)=84+4+5−(1+2+2)=8. In the second test case, the optimal subgraph is empty.

    最大权闭合子图

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<cstdio>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<vector>
      9 #include<set>
     10 #define maxn 200005
     11 #define MAXN 200005
     12 #define mem(a,b) memset(a,b,sizeof(a))
     13 const int N=200005;
     14 const int M=200005;
     15 const long long INF=0x3f3f3f3f3f3f3f3f;
     16 using namespace std;
     17 int n;
     18 struct Edge{
     19     int v,next;
     20     long long cap,flow;
     21 }edge[MAXN*20];
     22 int cur[MAXN],pre[MAXN],gap[MAXN],path[MAXN],dep[MAXN];
     23 int cnt=0;
     24 void isap_init()
     25 {
     26     cnt=0;
     27     memset(pre,-1,sizeof(pre));
     28 }
     29 void isap_add(int u,int v,long long w)
     30 {
     31     edge[cnt].v=v;
     32     edge[cnt].cap=w;
     33     edge[cnt].flow=0;
     34     edge[cnt].next=pre[u];
     35     pre[u]=cnt++;
     36 }
     37 void add(int u,int v,long long w){
     38     isap_add(u,v,w);
     39     isap_add(v,u,0);
     40 }
     41 bool bfs(int s,int t)
     42 {
     43     memset(dep,-1,sizeof(dep));
     44     memset(gap,0,sizeof(gap));
     45     gap[0]=1;
     46     dep[t]=0;
     47     queue<int>q;
     48     while(!q.empty())
     49     q.pop();
     50     q.push(t);
     51     while(!q.empty())
     52     {
     53         int u=q.front();
     54         q.pop();
     55         for(int i=pre[u];i!=-1;i=edge[i].next)
     56         {
     57             int v=edge[i].v;
     58             if(dep[v]==-1&&edge[i^1].cap>edge[i^1].flow)
     59             {
     60                 dep[v]=dep[u]+1;
     61                 gap[dep[v]]++;
     62                 q.push(v);
     63             }
     64         }
     65     }
     66     return dep[s]!=-1;
     67 }
     68 long long isap(int s,int t)
     69 {
     70     if(!bfs(s,t))
     71     return 0;
     72     memcpy(cur,pre,sizeof(pre));
     73     int u=s;
     74     path[u]=-1;
     75     long long ans=0;
     76     while(dep[s]<n)
     77     {
     78         if(u==t)
     79         {
     80             long long f=INF;
     81             for(int i=path[u];i!=-1;i=path[edge[i^1].v])
     82                 f=min(f,edge[i].cap-edge[i].flow);
     83             for(int i=path[u];i!=-1;i=path[edge[i^1].v])
     84             {
     85                 edge[i].flow+=f;
     86                 edge[i^1].flow-=f;
     87             }
     88             ans+=f;
     89             u=s;
     90             continue;
     91         }
     92         bool flag=false;
     93         int v;
     94         for(int i=cur[u];i!=-1;i=edge[i].next)
     95         {
     96             v=edge[i].v;
     97             if(dep[v]+1==dep[u]&&edge[i].cap-edge[i].flow)
     98             {
     99                 cur[u]=path[v]=i;
    100                 flag=true;
    101                 break;
    102             }
    103         }
    104         if(flag)
    105         {
    106             u=v;
    107             continue;
    108         }
    109         int x=n;
    110         if(!(--gap[dep[u]]))return ans;
    111         for(int i=pre[u];i!=-1;i=edge[i].next)
    112         {
    113             if(edge[i].cap-edge[i].flow&&dep[edge[i].v]<x)
    114             {
    115                 x=dep[edge[i].v];
    116                 cur[u]=i;
    117             }
    118         }
    119         dep[u]=x+1;
    120         gap[dep[u]]++;
    121         if(u!=s)
    122         u=edge[path[u]^1].v;
    123      }
    124      return ans;
    125 }
    126 
    127 int main(){
    128     int m,s,t;
    129     cin>>n>>m;
    130     s=0,t=n+m+1;
    131     int a,b;
    132     long long c;
    133     isap_init();
    134     for(int i=1;i<=n;i++){
    135         cin>>a;
    136         add(s,i,a);
    137     }
    138     long long sum=0;
    139     for(int i=1;i<=m;i++){
    140         cin>>a>>b>>c;
    141         sum+=c;
    142         add(a,i+n,INF);
    143         add(b,i+n,INF);
    144         add(i+n,t,c);
    145     }
    146     n=t+1;
    147     cout<<sum-isap(s,t)<<endl;
    148 }
    View Code
  • 相关阅读:
    页面适应UIWebView大小,不出现横向滚动条[转]
    switch case 遍历 table表头的时候使用枚举来便利 (switch 不支持字符串类型,用这种方式来达到使用目的)
    Builder 解析 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
    用2个层来显示 table 第一行 定位 效果。 支持ie6/ie7/ff/chrome,两个方向滚动条 ,保证最后一列也能对齐
    FORM 不换行的方法
    table 固定显示第一行 & 动态改变table高度
    select options 排序(保持option 对象完整性)
    JQuery ajax 如何设置同步调用(同时只能触发一个函数) 解决与层显示信息时候的冲突问题
    针对ie6 用层来实现select的title 提示属性 (增加含有滚动条情况的支持)
    定义新对象方法
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/10044247.html
Copyright © 2011-2022 走看看