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;
    }
  • 相关阅读:
    test
    dd 命令 sd卡系统迁移
    关于庖丁分词
    Linux source命令
    Linux系统查看系统是32位还是64位方法总结 in 创新实训
    总结这两天连续干掉的bug In 创新实训 智能自然语言交流系
    穷举法应用——搬砖块
    判断素数类问题汇总
    统计计算学生成绩类问题汇总
    C语言简明数据类型指南
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4437873.html
Copyright © 2011-2022 走看看