bzoj 2324 营救皮卡丘

来源:互联网 发布:编程差可以做it运维吗 编辑:程序博客网 时间:2024/04/30 07:11

floyd预处理 + 费用流

/**************************************************************    Problem: 2324    User: Clare    Language: C++    Result: Accepted    Time:300 ms    Memory:5408 kb****************************************************************/ #include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>using namespace std; #define N 310#define INF 0x3f3f3f3f int n,m,K,S,T;struct Edge{    int next,to,value,cost,from;}edge[N*N*2];int head[N],tot=1;int dis[N][N],d[N],pre[N];long long Ans;queue<int> Q;bool exist[N]; inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}    return x*f;} void Addedge(int u,int v,int w,int c){    tot++;edge[tot].next=head[u];edge[tot].to=v;edge[tot].from=u;    edge[tot].value=w;edge[tot].cost=c;head[u]=tot;    tot++;edge[tot].next=head[v];edge[tot].to=u;edge[tot].from=v;    edge[tot].value=0;edge[tot].cost=-c;head[v]=tot;} void Pre_floyd(){    for(int k=0;k<=n;k++)    {        for(int i=0;i<=n;i++)        {            for(int j=0;j<=n;j++)            {                if(k>i&&k>j)                    continue;                if(dis[i][j]>dis[i][k]+dis[k][j])                    dis[i][j]=dis[i][k]+dis[k][j];            }        }    }} bool SPFA(){    memset(d,INF,sizeof(d));    memset(exist,0,sizeof(exist));    d[S]=0;exist[S]=1;    Q.push(S);    while(!Q.empty())    {        int now=Q.front();Q.pop();        exist[now]=false;        for(int i=head[now];i;i=edge[i].next)        {            int v=edge[i].to;            if(edge[i].value>0&&d[v]>d[now]+edge[i].cost)            {                d[v]=d[now]+edge[i].cost;                pre[v]=i;                if(!exist[v])                {                    exist[v]=true;                    Q.push(v);                }            }        }    }    return !(d[T]==INF);} void DFS(){    int qwer=INF;    for(int i=pre[T];i;i=pre[edge[i].from])        qwer=min(qwer,edge[i].value);    for(int i=pre[T];i;i=pre[edge[i].from])    {        edge[i].value-=qwer;        edge[i^1].value+=qwer;        Ans+=(long long)edge[i].cost*qwer;    }} int main(){    n=read();m=read();K=read();    S=0;T=2*n+2;    for(int i=0;i<=n;i++)        for(int j=0;j<=n;j++)        {            if(i!=j)                dis[i][j]=INF;        }    for(int i=1;i<=m;i++)    {        int u=read(),v=read(),w=read();        dis[u][v]=min(dis[u][v],w);        dis[v][u]=dis[u][v];    }    Pre_floyd();    for(int i=1;i<=n;i++)    {        Addedge(S,i+n+1,1,0);        Addedge(i,T,1,0);    }    Addedge(S,n+1,K,0);    for(int i=0;i<=n;i++)        for(int j=i+1;j<=n;j++)        {            if(dis[i][j]!=INF)                Addedge(i+n+1,j,1,dis[i][j]);        }    while(SPFA())        DFS();    cout<<Ans<<endl;    return 0;}


0 0
原创粉丝点击