网络流问题的常见套路

本文在接下来的一段时间内可能会经常扩充或修改,如有谬误敬请谅解。[2017.11.24]

“拆点”

拆点,顾名思义,就是把一个点拆成两个点。因为在网络流的模型中,割特指边集而非点集,所以想要实现“可以被割掉的点”,就用用到拆点思想。另外,这种方法也可以被理解为:使点同边一样有一个容量上限。

把点A分成两个,一个叫A1,表示A的“入点”;另一个叫A2,表示A的“出点”。A的所有出边都从A2连出,所有入边都连向A1。再连一条边从A1指向A2,其边权为点A的“点容量”。

例题:[USACO5.4]奶牛的电信(copy from 洛谷,特此表示感谢)

P1345 [USACO5.4]奶牛的电信Telecowmunication

题目描述

农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,…,a(c),且a1与a2相连,a2与a3相连,等等,那么电脑a1和a(c)就可以互发电邮。

很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。

有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。

以如下网络为例:

1*

/ 3 - 2*

这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。

输入输出格式

输入格式: 第一行
四个由空格分隔的整数:N,M,c1,c2.N是电脑总数(1<=N<=100),电脑由1到N编号。M是电脑之间连接的总数(1<=M<=600)。最后的两个整数c1和c2是上述两头奶牛使用的电脑编号。连接没有重复且均为双向的(即如果c1与c2相连,那么c2与c1也相连)。两台电脑之间至多有一条连接。电脑c1和c2不会直接相连。

第2到M+1行 接下来的M行中,每行包含两台直接相连的电脑的编号。

输出格式: 一个整数表示使电脑c1和c2不能互相通信需要坏掉的电脑数目的最小值。

输入输出样例

样例输入:

3 2 1 2
1 3
2 3

样例输出:

1

附上代码

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;

const int maxn=605,INF=0x3f3f3f3f;

struct Dinic{
    int n,s,t;
    struct Edge{
        int from,to,cap,flow;
    };
    vector<int>G[maxn];
    vector<Edge>edges;

    int cur[maxn],d[maxn];
    bool vis[maxn];

    void addedge(int f,int t,int c){
        edges.push_back((Edge){f,t,c,0});
        edges.push_back((Edge){t,f,0,0});
        int m=edges.size();
        G[f].push_back(m-2);
        G[t].push_back(m-1);
    }

    bool BFS(){
        //memset(d,0,sizeof(d));
        memset(vis,0,sizeof(vis));
        queue<int>Q;
        Q.push(s);d[s]=0;vis[s]=1;
        while(!Q.empty()){
            int x=Q.front();Q.pop();
            for(int i=0;i<G[x].size();i++){
                Edge& e=edges[G[x][i]];
                if(!vis[e.to] && e.cap>e.flow){
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int DFS(int x,int a){
        if(x==t || a==0)return a;
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++){
            Edge& e=edges[G[x][i]];
            if(e.cap>e.flow && d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    }

    int MaxFlow(int S,int T){
        s=S;t=T;int flow=0;
        while(BFS()){
            memset(cur,0,sizeof(cur));
            flow+=DFS(S,INF);
        }
        return flow;
    }
}dinic;

int main(){
    int N,M,c1,c2;scanf("%d%d%d%d",&N,&M,&c1,&c2);
    for(int i=1;i<=N;i++){
        dinic.addedge(i,i+N,1);
    }
    for(int i=1;i<=M;i++){
        int x,y;scanf("%d%d",&x,&y);
        dinic.addedge(x+N,y,INF);
        dinic.addedge(y+N,x,INF);
    }
    int mf=dinic.MaxFlow(c1+N,c2);
    printf("%d\n",mf);
    return 0;
}

本题求至少要删除多少个点使C1、C2不连通,问题的实质是一个最小割,跑一个最大流即可,因为只允许割点,不允许割边,所以原有的边边权都为INF。点权为1,表示每个点最多只能被删除一次。

### 回答1: 股市黑嘴荐股常见套路有以下几种: 1. 虚假宣传: 利用虚假信息、夸大公司业绩等方式吸引投资者买入股票。 2. 关系网络: 利用人脉关系、宣传传销等方式吸引投资者买入股票。 3. 利益输送: 通过各种手段将股票价格推高,然后再以高价卖出获利。 4. 消息操纵: 通过控制信息流、散布虚假消息等方式影响股票价格。 5. 关注度操纵: 通过制造关注度、推销热点等方式吸引投资者买入股票。 投资者在投资股票时,需要格外谨慎,不要轻信股市黑嘴的荐股。要多方了解公司、行业、市场等信息,做到理性、客观评估。 ### 回答2: 股市黑嘴荐股套路是指一些人在股市中以虚假、夸大或不真实的言辞来推荐股票,以达到牟利或欺骗他人的目的。以下是一些常见的股市黑嘴荐股套路。 1. 炒作热点股:黑嘴以炒作热点股为手段,吸引更多的投资者参与其中,推高股票价格并进行高价抛售,从中获取差价利润。他们可能使用夸大的语言来吹捧相关公司业绩或前景,以吸引投资者注意。 2. 虚假消息:黑嘴散布虚假消息,通过煽动市场情绪来促使股票价格起伏。他们可能传播关于某公司即将发布利好消息或与大型企业达成合作的不实言论,以引起投资者的兴趣并推高股价。 3. 推销低价股:黑嘴常常推销低价股,利用低价吸引投资者购买,然后通过大幅抬高股价后高价抛售,获取利润并导致投资者亏损。 4. 虚构研报:一些黑嘴可能发布虚构的研报,来歪曲股票的真实价值并引导市场情绪。他们可能通过夸大公司业绩或前景来吸引投资者,同时掩盖相关风险和不利因素。 5. 特定机构或公司与黑嘴合谋:在一些情况下,黑嘴与特定机构或公司合谋,共同炒作股票。这种合谋可能会导致股价异常波动,给投资者带来风险。 为了避免成为股市黑嘴荐股的受害者,投资者应该保持冷静、理性的态度,通过多方面的研究和分析来做出决策,而不是盲目跟随市场热点或听信未经认证的消息。此外,投资者应该选择正规渠道获取信息,并学习基本的投资知识和技巧,以提高自己的判断能力。最重要的是,投资者应该意识到股市投资存在风险,并根据自身的风险承受能力做出相应的投资决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值