POJ 3308

Posted Grary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3308相关的知识,希望对你有一定的参考价值。

http://poj.org/problem?id=3308

考虑答案不是乘积而是和的做法,

因为对于每一个伞兵我们要么在这行内安装大炮消灭它

要么在这列中安装大炮消灭它,所以容易看出这是一个最小边覆盖集的问题

所以转化成乘积需要用到一个特殊的方法(以前没用过)

\(ans=a_1a_2\cdots a_k\)
\(ans=10^{\lg ans}=10^{\lg a_1a_2\cdots a_k}\)
\(ans=10^{\lg a_1+\lg a_2+\cdots \lg a_k}\)
这样就将乘法转化成加法了




不过还是遇到一个问题不知道如何解决
这个边的流量如果是浮点数如何解决
…………………………………………

#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#define N 1000005
#define inf 0x3f3f3f3f
using namespace std;

int read(){
    int s=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);s=s*10+ch-'0',ch=getchar());
    return s;
}

struct Edge{
    int to,nxt,cap;
};

int que[N];
int h,qt;

struct Dinic{
    Edge e[N];
    bool vis[N];
    int tot,s,t,n;
    int d[N],cur[N],head[N];
    Dinic(){tot=1;}
    void add(int u,int v,int f){
        e[++tot].to=v;
        e[tot].cap=f;
        e[tot].nxt=head[u];
        head[u]=tot;
        e[++tot].to=u;
        e[tot].cap=0;
        e[tot].nxt=head[v];
        head[v]=tot;
    }
    bool bfs(){
        memset(vis,false,sizeof(vis));
        for(int i=0;i<=n;++i)cur[i]=head[i];
        que[qt=1]=s,h=0;int top,to;d[s]=0;vis[s]=1;
        while(h<qt){
            top=que[++h];
            for(int i=head[top];i;i=e[i].nxt)
                if(!vis[e[i].to]&&e[i].cap){
                    to=e[i].to;que[++qt]=to;
                    vis[to]=true;d[to]=d[top]+1;
                    if(to==t)return true;
                }
        }
        return vis[t];
    }
    int dfs(int x,int fl){
        if(x==t)return fl;
        int flow=0,f,to;
        for(int &i=cur[x];i;i=e[i].nxt){
            to=e[i].to;
            if(d[to]==d[x]+1&&e[i].cap)
            if(f=dfs(to,min(fl,e[i].cap))){
                e[i].cap-=f;fl-=f;
                e[i^1].cap+=f;flow+=f;
                if(fl<=0)break;
            }
        }
        if(fl)d[x]=-1;
        return flow;
    }
    int maxflow(int s,int t){
        this->s=s;this->t=t;
        int ans=0;
        while(bfs())ans+=dfs(s,inf);
        return ans;
    }
};


int co[N];
int st[N];

double Co[N];
double St[N];

int main(){
    Dinic f;
    int n,m,k,s,t,a,b,c;
    scanf("%d%d%d",&n,&m,&k);
    f.n=2+n+m;
    for(int i=1;i<=n;++i){
        cin>>co[i];
        Co[i]=log10(co[i]);
    }
    for(int i=1;i<=n;++i)
        f.add(1,i+1,Co[i]);
    for(int j=1;j<=m;++j)
        f.add(n+m+2,n+1+i);
    for(int i=1;i<=n;++i){
        cin>>st[i];
        St[i]=log10(st[i]);
    }
    for(int i=1;i<=k;++i){
        cin>>a>>b;
        f.add(a,b,inf);
    }
    cout<<f.maxlflow(1,n+m+2);
    return 0;
}

以上是关于POJ 3308的主要内容,如果未能解决你的问题,请参考以下文章

poj 3308 Paratroopers(最小点权覆盖)

poj 3308 Paratroopers 最小割 最小点权覆盖

POJ3308 Paratroopers(网络流)(最小割)

POJ 3308 最少点集覆盖

poj3308 Paratroopers --- 最小点权覆盖-&gt;最小割

POJ2778DNA Sequence(AC自动机)