Mining Station on the Sea (Dijktra + KM)

题目链接

/*
* @Author: Achan
* @Date:   2018-10-29 19:10:05
* @Last Modified by:   Achan
* @Last Modified time: 2018-10-29 21:57:25
*/
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
#include<vector> 
#include<queue>
#include<cmath> 
using namespace std;

#define X             first
#define Y             second
#define eps          1e-2
#define gcd         __gcd
#define pb             push_back
#define PI             acos(-1.0)
#define lowbit(x)     (x)&(-x)
#define fin         freopen("in.txt","r",stdin);
#define fout        freopen("out.txt","w",stdout);
#define bug         printf("!!!!!\n");
#define mem(x,y)    memset(x,y,sizeof(x))
#define rep(i,j,k)  for(int i=j;i<(int)k;i++)
#define per(i,j,k)  for(int i=j;i<=(int)k;i++)
#define pset(x)     setiosflags(ios::fixed)<<setprecision(x)
#define io std::ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);

typedef long long ll;
typedef long double LD; 
typedef pair<int,int> pii;
typedef unsigned long long ull; 

const int inf  = 1<<30;
const ll  INF  = 1e18 ;
const int mod  = 1e9+7;
const int maxn = 4e2+2;
const int mov[4][2] = {-1,0,1,0,0,1,0,-1};
const int Mov[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
 
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int tot;
int n,m; 
int head[maxn];  
struct edge
{
    int w;
    int to;
    int nex;
}E[maxn*maxn +maxn];  
inline void init(){tot = 0; memset(head,-1,sizeof(head)); }

inline void add_edge(int u, int v, int w)
{
    E[tot].to =  v;
    E[tot].w  = w;
    E[tot].nex = head[u];
    head[u] = tot++;
}
int dis[maxn];
int vis[maxn];
void Dijktra(int s)
{
    memset(vis,0,sizeof(vis));
    fill(dis,dis+n+m+1,inf); 
    dis[s] = 0;
    priority_queue <pair<int , int> > q;
    q.push(make_pair(0,s)); 
    while(!q.empty())
    {
        int cur = q.top().second;
        q.pop();
        if(vis[cur]) continue;
        vis[cur] = 1;
        for(int i = head[cur]; ~i; i = E[i].nex)
        {
            int w = E[i].w;
            int to = E[i].to;
            if(!vis[to] && dis[to] > dis[cur] + w) //vis[to] 不要习惯写成vis[i]
            {
                dis[to] = dis[cur] + w;
                q.push(make_pair(-dis[to] , to));
            }
        }
    }
}

int ex_b[maxn],ex_g[maxn];
bool visb[maxn],visg[maxn];
int match[maxn],slack[maxn];
int mp[maxn][maxn];

bool DFS(int cur)
{
    visg[cur] = 1;
    for(int i = 1; i<= n;i++)
    {
        if(visb[i]) continue;
        int gap = ex_b[i] + ex_g[cur] - mp[cur][i];
        if(!gap) 
        {
            visb[i] = 1;
            if(match[i]==-1 || DFS(match[i]))
            {
                match[i] = cur;
                return true;
            }
        }
        else slack[i] = min(slack[i],gap); 
    }
    return false;
}
void KM()
{
    memset(ex_b,0,sizeof(ex_b));
    memset(match,-1,sizeof(match)); 
     for(int i = 1; i<=n ; i++)
    {
        fill(slack,slack + n + 1,inf);
        while(1)
        {
            memset(visb,0,sizeof(visb));
            memset(visg,0,sizeof(visg));
            if(DFS(i)) break;
            int d = inf;
            for(int j = 1; j<=n ; j++) if(!visb[j]) d = min(d,slack[j]);
            for(int j = 1; j<=n ; j++)
            {
                if(visg[j]) ex_g[j] -= d; 
                if(visb[j]) ex_b[j] += d;  
                else slack[j] -= d; 
             }
         }    
    }
    int ans = 0;
    for(int i = 1; i<=n ;i++)  ans += mp[match[i]][i];
    printf("%lld\n",-ans); 
}

int op[maxn];

int main(void)
{
    int k,p; 
    while(~scanf("%d%d%d%d",&n,&m,&k,&p))
    {
        init();
        for(int i=1;i<=n;i++) op[i] = read();
        for(int i=1;i<=k;i++) 
        {
            int u,v,w;
            u = read(), v = read(), w = read(); 
            add_edge(u,v,w);
            add_edge(v,u,w);
        }
        for(int i=1;i<=p;i++)
        {
            int u,v,w;
            u = read(), v = read(), w = read(); 
            add_edge(v,u+m,w);  //矿与港口建单边     
        }
        //建立 n*n二分图 
        for(int i=1;i<=n;i++)  //n个船 
        {
            Dijktra(op[i]);  int maxg = -inf; 
            for(int j = m+1; j<= m+n ; j++) //遍历n个港口
                mp[i][j-m] = -dis[j] , maxg = max(maxg, -dis[j]);
            ex_g[i] = maxg; 
        }
        KM();
    }

}


Accepted	time:452MS	memory:2328K	length:4068 B
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值