ACM hdu5352 最小费用最大流 模板 网络流

针对一个包含多个城市的国家,在经历地震后,通过一系列操作如重建城市、新建道路及地震破坏等,实现最大数量的城市重建,并找出字典序最小的重建方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先建图,求字典序最小,转化成前面的费用较大,的费用流

for (int i=0; i<n; i++) cost[i]=n-i; //费用逐渐递减

2015多校第5场-hdu5352

起初用ISAP最大流WA了,再后来用了费用流模板TLE,最后使用了大白书的模板AC,另外感谢FZ的代码


/*
 * Author: NICK WONG
 * Created Time:  2015/8/4 13:50:07
 * File Name: 1010.cpp
 */
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
#define out(x) cout<<#x<<": "<<x<<endl
const double eps(1e-8);
const int maxn=210;
const long long maxint=-1u>>1;
const long long maxlong=maxint*maxint;
typedef long long lint;
int tt,_n,_m,k,mp[510][maxn],year,ans;
bool a[maxn][maxn],vis[maxn];
#define MAXN 710
#define INF 1000000000

void init()
{
    cin>>_n>>_m>>k;
}

void dfs(int x)
{
    vis[x]=true;
    mp[year][++mp[year][0]]=x;
    for (int i=1; i<=_n; i++)
        if (!vis[i] && a[x][i]) dfs(i);
}

#define a aaa
struct Edge {
    int from , to , cap , flow , cost;
};

int n ;
vector<Edge> edges;
vector<int> G[MAXN];
int inq[MAXN];
int d[MAXN];
int p[MAXN];
int a[MAXN];

void G_init()
{
    for ( int i = 0 ; i < n ; i++ ) G[i].clear();
    edges.clear();
}

void addedge ( int from , int to , int cap , int cost ) 
{
    edges.push_back((Edge){from,to,cap,0,cost});
    edges.push_back((Edge){to,from,0,0,-cost});
    int m = edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
}

bool spfa ( int s , int t , int &flow , int &cost ) 
{
    for ( int i = 0 ; i < n ; i++ ) d[i] = INF;
    memset ( inq  , 0 , sizeof (inq ) );
    d[s] = 0; inq[s] = 1; p[s] = 0 ; a[s] = INF;
    
    queue<int> Q;
    Q.push(s);
    while ( !Q.empty() ) {
        int u = Q.front() ; Q.pop();
        inq[u] = 0;
        for ( int i = 0 ; i < (int) G[u].size() ; i++ ) {
            Edge &e = edges[G[u][i]];
            if ( e.cap > e.flow && d[e.to] > d[u] + e.cost ) {
                d[e.to] = d[u] + e.cost;
                p[e.to] = G[u][i];
                a[e.to] = min( a[u] , e.cap - e.flow );
                if ( !inq[e.to] ) { Q.push(e.to); inq[e.to] = 1; }
            }
        }
    }
    if ( d[t] == INF ) return false;
    flow += a[t];
    cost += d[t] * a[t];//d[t]增广单位流量的费用 * a[t]流量
    int u = t;
    while ( u != s ) {
        edges[p[u]].flow += a[t];
        edges[p[u]^1].flow -= a[t];
        u = edges[p[u]].from;
    }
    return true;
}

int Mincost (int s, int t) 
{
    int flow = 0 , cost = 0;
    //int time=10;
    while ( spfa(s,t,flow,cost) )
    {
        //out(flow);
        //if (--time)  break;
    }
    return flow;
}
#undef a

void work()
{
    memset(a,false,sizeof(a));
    memset(mp,0,sizeof(mp));
    year=0;
    for (int i=1; i<=_m; i++)
    {
        int type,x,y,p;
        scanf("%d",&type);
        if (type==1)
        {
            scanf("%d",&x);
            year++;
            memset(vis,false,sizeof(vis));
            dfs(x);
        } else 
            if (type==2)
            {
                scanf("%d%d",&x,&y);
                a[x][y]=a[y][x]=true;
            } else
                if (type==3)
                {
                    scanf("%d",&p);
                    for (int j=1; j<=p; j++)
                    {    
                        scanf("%d%d",&x,&y);
                        a[x][y]=a[y][x]=false;
                    }
                }
    }
    /*
       out(year);
       for (int i=1; i<=year; i++)
       {
       for (int j=1; j<=mp[i][0]; j++)
       cout<<mp[i][j]<<" ";
       cout<<endl;
       } */
    //memset(cost,0,sizeof(cost));
    //memset(mat,0,sizeof(mat));
    //memset(flow,0,sizeof(flow));
    n=2+_n+year;
    G_init();
    for (int i=1; i<=_n; i++)
        addedge(0,i,1,0);
    //for (int i=year; i>=1; i--)
    for (int i=1; i<=year; i++)
        for (int j=1; j<=mp[i][0]; j++)
            addedge(mp[i][j],_n+i,1,0);
            //mat[mp[i][j]][_n+i]=1;
    for (int i=1; i<=year; i++)
    {
        addedge(_n+i,1+_n+year,k,year-i);
        //addedge(1+_n+year,_n+i,0,-(year-i));
        //mat[_n+i][1+_n+year]=k;
        //cost[_n+i][1+_n+year]=year-i;
        //cost[1+_n+year][_n+i]=-(year-i);//reflect
    }
    //G.addedge(2+_n+year,1+_n+i,k);
    //ans=G.max_flow(2+_n+year,1);
    //out(122);
    ans=Mincost(0,1+_n+year);
    cout<<ans<<endl;
    //out(233);
    int build[510];
    memset(build,0,sizeof(build));
    for ( int i = 0 ; i < (int) G[1+_n+year].size() ; i++ ) 
    {
        Edge& e = edges[G[1+_n+year][i]];
        build[e.to]=-e.flow;
    }
    for (int i=1; i<=year; i++)
    {
        //out(G.head[1+_n+i]);
        cout<<build[_n+i];
        if (i==year) cout<<endl; else cout<<" ";   
    }
}

int main()
{
    cin>>tt;
    while(tt--)
    {
        init();
        work();
    } 
    return 0;
}



题目:

MZL's City

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 150    Accepted Submission(s): 41


Problem Description
MZL is an active girl who has her own country.

Her big country has N cities numbered from 1 to N.She has controled the country for so long and she only remebered that there was a big earthquake M years ago,which made all the roads between the cities destroyed and all the city became broken.She also remebered that exactly one of the following things happened every recent M years:

1.She rebuild some cities that are connected with X directly and indirectly.Notice that if a city was rebuilt that it will never be broken again.

2.There is a bidirectional road between city X and city Y built.

3.There is a earthquake happened and some roads were destroyed.

She forgot the exactly cities that were rebuilt,but she only knew that no more than K cities were rebuilt in one year.Now she only want to know the maximal number of cities that could be rebuilt.At the same time she want you to tell her the smallest lexicographically plan under the best answer.Notice that 8 2 1 is smaller than 10 0 1.
 


Input
The first contains one integer T(T<=50),indicating the number of tests.

For each test,the first line contains three integers N,M,K(N<=200,M<=500,K<=200),indicating the number of MZL’s country ,the years happened a big earthquake and the limit of the rebuild.Next M lines,each line contains a operation,and the format is “1 x” , “2 x y”,or a operation of type 3.

If it’s type 3,first it is a interger p,indicating the number of the destoyed roads,next 2*p numbers,describing the p destoyed roads as (x,y).It’s guaranteed in any time there is no more than 1 road between every two cities and the road destoyed must exist in that time.
 


Output
The First line Ans is the maximal number of the city rebuilt,the second line is a array of length of tot describing the plan you give(tot is the number of the operation of type 1).
 


Sample Input
  
1 5 6 2 2 1 2 2 1 3 1 1 1 2 3 1 1 2 1 2
 


Sample Output
  
3 0 2 1
Hint
No city was rebuilt in the third year,city 1 and city 3 were rebuilt in the fourth year,and city 2 was rebuilt in the sixth year.
 


Source
 


Recommend
wange2014   |   We have carefully selected several similar problems for you:   5351  5350  5349  5348  5347 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值