zoukankan      html  css  js  c++  java
  • POJ 3216 Repairing Company(二分图匹配)

    题意:给定n条街道,用一个矩阵描述两两之间的距离,m个任务,p,t,d分别为所在街道、任务起始时间、任务结束时间,求完成所有任务所需最少人数;

    思路:先用floyd处理两两间最短路,然后,若完成i任务的人能够完成j任务,则在i,j间建一条边,所需人数为总任务数减最大匹配数;匈牙利算法;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define INF 0x3f3f3f3f
    struct node
    {
        int p,t,d;
    }q[500010];
    int n,m;
    int link[5500],vis[5500];
    int mm[550][550],g[550][550];
    int dfs(int t)//增广路
    {
        int i,j,k;
        for(i=1;i<=m;i++)
        {
            if(g[t][i]&&!vis[i])
            {
                vis[i]=1;
                if(link[i]==-1||dfs(link[i]))
                {
                    link[i]=t;
                    return 1;//找到新增广路
                }
            }
        }
        return 0;
    }
    int hungry()//最大匹配数
    {
        int i,j,k,num=0;
        memset(link,-1,sizeof(link));
        for(i=1;i<=m;i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i)) num++;
        }
        return num;
    }
    int main()
    {
        int i,j,k;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(n==0&&m==0) break;
            memset(mm,0,sizeof(mm));
            memset(g,0,sizeof(g));
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=n;j++)
                {
                    scanf("%d",&mm[i][j]);
                    if(mm[i][j]==-1) mm[i][j]=INF;
                }
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&q[i].p,&q[i].t,&q[i].d);
            }
            for(i=1;i<=n;i++)//floyd算各点间最短路
            {
                for(j=1;j<=n;j++)
                {
                    for(k=1;k<=n;k++)
                    {
                        if(mm[j][k]>mm[j][i]+mm[i][k]) mm[j][k]=mm[j][i]+mm[i][k];
                    }
                }
            }
            for(i=1;i<=m;i++)//构建二分图
            {
                for(j=1;j<=m;j++)
                {
                    int u=q[i].p;
                    int v=q[j].p;
                    if(i==j||mm[u][v]==INF) continue;
                    if(q[i].t+q[i].d+mm[u][v]<=q[j].t) g[i][j]=1;
                }
            }
            printf("%d
    ",m-hungry());
        }
        return 0;
    }
  • 相关阅读:
    PHP form 表单传参明细研究
    php返回数据库查询时出现Resource id #2
    AJAX避免服务器调用上个页面缓存的办法
    错误提示sudo: no tty present and no askpass program specified Sorry, try again.
    lua创建文件和文件夹
    ngx.lua中遇到的小问题2
    [Puzzle] 蚂蚁路线碰撞问题
    [问题记录] 操作符连写
    [工具] XMind
    Qt Creator快捷键
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4437873.html
Copyright © 2011-2022 走看看