zoukankan      html  css  js  c++  java
  • 【二分图匹配入门专题1】M

    There are N cities in our country, and M one-way roads connecting them. Now Little Tom wants to make several cyclic tours, which satisfy that, each cycle contain at least two cities, and each city belongs to one cycle exactly. Tom wants the total length of all the tours minimum, but he is too lazy to calculate. Can you help him? 

    InputThere are several test cases in the input. You should process to the end of file (EOF). 
    The first line of each test case contains two integers N (N ≤ 100) and M, indicating the number of cities and the number of roads. The M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from city A to city B, whose length is C. (1 ≤ A,B ≤ N, A ≠ B, 1 ≤ C ≤ 1000). 
    OutputOutput one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1. 
    Sample Input

    6 9
    1 2 5
    2 3 5
    3 1 10
    3 4 12
    4 1 8
    4 6 11
    5 4 7
    5 6 9
    6 5 4
    6 5
    1 2 1
    2 3 1
    3 4 1
    4 5 1
    5 6 1

    Sample Output

    42
    -1
    
    
            
     

    Hint

     In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42. 
            
     

    题意:输入n个顶点m条边,让这些顶点形成环,至少包括两个顶点.输出最小的完备匹配和,如果不存在,输出-1。

    思路:把一个点一分为二,就形成了两个集合,求最小匹配,则将权值取负后求最大匹配,最后返回负值。如果图由多个有向环构成,则一定存在完备匹配,如果有权值最大的完备匹配存在,则一定是这个图的最优完备匹配的值,如果有任何一个匹配边是初始化的边权值,说明这个完备匹配不存在。

    之前嫌弃题水,现在又写的头疼,今天一天到现在才出了3题,自己真的好菜啊,什么时候能像师父那样厉害就好了,感觉算法真的需要自己理解了才能够应对各种变形,就这道题就超时了

    5遍,我怎么知道要判断重边啊~~~

    #include<stdio.h>
    #include<string.h>
    #define N 210
    #define INF 0x3f3f3f3f
    
    int map[N][N];
    int ans,d;
    int w[N][N],lx[N],ly[N];
    int linker[N],visx[N],visy[N];
    int n,m,nx,ny;
    
    int dfs(int x)
    {
        int y,tmp;
        visx[x] = 1;
        for(y = 1; y <= ny; y ++)
        {
            if(!visy[y])
            {
                tmp = lx[x] + ly[y] - w[x][y];
                if(!tmp)
                {
                    visy[y] = 1;
                    if(linker[y]==-1||dfs(linker[y]))
                    {
                        linker[y] = x;
                        return 1;
                    }
                }
                else if( d > tmp)
                    d = tmp;
            }
        }
        return 0;
    }
    
    int KM()
    {
        int x,y,i,j,sum;
        memset(linker,-1,sizeof(linker));
        memset(ly,0,sizeof(ly));
        for(x = 1; x <= nx; x ++)
            for(y = 1,lx[x] = -INF; y <= ny; y ++)
                if(lx[x] < w[x][y])
                    lx[x] = w[x][y];
                    
        for(x = 1; x <= nx; x ++)
        {
            while(1)
            {
                d = INF;
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                if(dfs(x))
                    break;
                for(i = 1; i <= nx; i ++)
                    if(visx[i])
                        lx[i] -= d;
                for(i = 1; i <= ny; i ++)
                    if(visy[i])
                        ly[i] += d;
            }
        }
        sum = 0;
        for(i = 1; i <= ny; i ++)
        {
            if(w[linker[i]][i] != -INF)
                sum += w[linker[i]][i];
            else
                return -1;
        }
        return -sum;
    }
    
    int main()
    {
        int t1,t2,t3;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            nx = ny = n;
            for(int i = 1; i <= n; i ++)
                for(int j = 1; j <= n; j ++)
                    w[i][j] = -INF;
            for(int i = 1; i <= m; i ++)
            {
                scanf("%d%d%d",&t1,&t2,&t3);
                if(-t3 > w[t1][t2])//重复输入取小值 
                    w[t1][t2] = -t3;
            }
            ans = KM();
            printf("%d
    ",ans);    
        }
        return 0;
    }
  • 相关阅读:
    GitHub转华为软件开发云详细教程
    如何将项目管理从禅道迁移到华为软件开发云
    华为CloudIDE免费公测,带你出坑带你飞
    闲谈 | 敏捷宣言说了什么
    Eclipse安装Git插件以及通过Git导入华为软件开发云项目
    终于等到你!MobileTest免费公测,华为带你走出安卓适配大坑
    华为软件开发云测评报告三:测试管理
    华为软件开发云发布管理测评报告
    你真的知道敏捷和迭代吗?
    ThoughtWorks、Teambition、Trello、Slack、DevCloud 主流敏捷软件开发工具平台比较
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7358170.html
Copyright © 2011-2022 走看看