Mining Station on the Sea—-dijkstra+KM

來源:互聯網
上載者:User

題目:http://acm.hdu.edu.cn/showproblem.php?pid=2448

思路:最短路+KM

註:station與port之間的邊是有向邊.(就是因為這一點WA了N次)

原始碼:

#include <stdio.h>#include <string.h>#include <algorithm>#define N 305#define INF 1e9using namespace  std;int n,m,k,p;int u,v,w;int a[N],dist[N],vis[N],map[N][N];int g[N][N],nx,ny; //需要初始化    nx是X的頂點數  ny是Y的頂點數int mx[N],my[N],lx[N],ly[N]; //lx[],ly[]為KM演算法中Xi與Yi的頂點標號  mx[]是匹配後X中對應的Y的頂點編號  my[]是匹配後Y中對應的X的頂點編號bool sx[N],sy[N]; //標記是否在交錯樹上int prev[N],slack[N]; //prev[i]為Y中i點在交錯樹上的前點;slack為鬆弛量int q[2*N],head,tail;void dij(int s,int n){    int min,tmp;    for(int i=1;i<=n;i++)  {  dist[i]=INF;  vis[i]=0; }    dist[s]=0;    for(int i=1;i<=n;i++)    {       min=INF;       for(int j=1;j<=n;j++)        if(!vis[j]&&dist[j]<min)        {            tmp=j;            min=dist[j];        }        vis[tmp]=1;        for(int j=1;j<=n;j++)         if(map[tmp][j]>=0)            {                if(dist[j]>min+map[tmp][j])                dist[j]=min+map[tmp][j];            }    }}void augment(int v){ //增廣    while(v!=-1){        int pv=mx[prev[v]];        mx[prev[v]]=v; my[v]=prev[v];v=pv;    }}bool bfs(){    while(head!=tail){        int p=q[head++],u=p>>1;        if(p & 1){            if(my[u]==-1){ augment(u);return true;            }            else {  q[tail++]=my[u]<<1; sx[my[u]]=true;            }        }        else            for(int i=0;i<ny;i++)                if(sy[i]) continue;                else if(lx[u]+ly[i]!=g[u][i]){                        int ex=lx[u]+ly[i]-g[u][i];                        if(slack[i]>ex){ slack[i]=ex; prev[i]=u; }                        }                    else { prev[i]=u; sy[i]=true; q[tail++]=i*2+1; }    }    return false;}int KMmatch(bool maxsum ){ //預設為最大權匹配    int i,j,ex,cost=0;    if(!maxsum) for(i=0;i<nx;i++)        for(j=0;j<ny;j++) g[i][j]*=-1;    memset(mx,-1,sizeof(mx));    memset(my,-1,sizeof(my));    memset(ly,0,sizeof(ly));    for(i=0;i<nx;i++)        for(lx[i]=-INF,j=0;j<ny;j++)            lx[i]=max(lx[i],g[i][j]);    for(int live=0;live<nx;live++){        memset(sx,0,sizeof(sx));        memset(sy,0,sizeof(sy));        for(i=0;i<ny;i++)slack[i]=INF;            head=tail=0; q[tail++]=live*2; sx[live]=true;            while(!bfs()){                for(ex=INF,i=0;i<ny;i++)    if(!sy[i]) ex=min(ex,slack[i]);                for(i=0;i<nx;i++)    if(sx[i])lx[i]-=ex;                for(j=0;j<ny;j++){ if(sy[j])ly[j]+=ex;slack[j]-=ex;}                for(i=0;i<ny;i++)                if(!sy[i] && slack[i]==0){q[tail++]=i*2+1;sy[i]=true;}            }    }    if(!maxsum) for(i=0;i<nx;i++) for(j=0;j<ny;j++) g[i][j]*=-1;    for(i=0;i<nx;i++)cost+=g[i][mx[i]];    return cost;}int main(){    //freopen("D:\\a.txt","r",stdin);    while(~scanf("%d %d %d %d",&n,&m,&k,&p))    {        memset(map,-1,sizeof(map));        memset(g,INF,sizeof(g));        memset(a,0,sizeof(a));        for(int i=1;i<=n;i++)        scanf("%d",&a[i]);        for(int i=0;i<k;i++)        {            scanf("%d %d %d",&u,&v,&w);            map[u][v]=map[v][u]=w;        }        for(int i=0;i<p;i++)        {            scanf("%d %d %d",&u,&v,&w);           map[v][m+u]=w;        }        for(int i=1;i<=n;i++)        {            dij(a[i],m+n);            for(int j=m+1;j<=m+n;j++)              g[i-1][j-m-1]=dist[j];        }        nx=ny=n;        printf("%d\n",KMmatch(false));    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.