Mining Station on the Sea----dijkstra+KM
2012-08-05 22:14
162 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2448
思路:最短路+KM
注:station与port之间的边是有向边.(就是因为这一点WA了N次)
源代码:
思路:最短路+KM
注:station与port之间的边是有向边.(就是因为这一点WA了N次)
源代码:
#include <stdio.h> #include <string.h> #include <algorithm> #define N 305 #define INF 1e9 using namespace std; int n,m,k,p; int u,v,w; int a ,dist ,vis ,map ; int g ,nx,ny; //需要初始化 nx是X的顶点数 ny是Y的顶点数 int mx ,my ,lx ,ly ; //lx[],ly[]为KM算法中Xi与Yi的顶点标号 mx[]是匹配后X中对应的Y的顶点编号 my[]是匹配后Y中对应的X的顶点编号 bool sx ,sy ; //标记是否在交错树上 int prev ,slack ; //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; }
相关文章推荐
- HDU 2448 Mining Station on the Sea 最短路+KM
- 【KM匹配】 HDOJ 2448 Mining Station on the Sea
- HDU 2448 Mining Station on the Sea(floyd+KM)
- hdu 2448 Mining Station on the Sea(最短路径+KM)
- hdu 2448 Mining Station on the Sea【最短路Floyd+KM 最佳匹配】
- HDU 2448 Mining Station on the Sea(KM最大匹配+floyd)
- HDU 2448 Mining Station on the Sea(最小费用流+spfa,超了n次的题)
- hdu 2448 Mining Station on the Sea【费用流】本代码思路仅供参考
- HEU Mining Station on the Sea(最小费用最大流)
- HDU-2448 Mining Station on the Sea
- HDU 2448 Mining Station on the Sea
- HDU 2448 Mining Station on the Sea(最小费用最大流, KM算法)
- HDU 2448 Mining Station on the Sea(Floyd+最优匹配)
- HDU 2448 Mining Station on the Sea(Floyd+最优匹配)
- HDU_2448_Mining Station on the Sea(最短路 + 最小费用流)
- HDU 2448 Mining Station on the Sea 费用流
- hdu 2448 Mining Station on the Sea(最短路+费用流)
- HDU 2448 Mining Station on the sea(KM算法)
- HDU 2448 Mining Station on the Sea
- hdu 2448 Mining Station on the Sea(KM匹配//费用流)