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;
    }
  • 相关阅读:
    30道四则运算
    《梦断代码》第0章读书随笔
    《梦断代码》阅读计划
    [记录] Mybatis原理
    GitLab登录密码重置后无法使用idea拉取代码提交代码问题解决
    写邮件和回复邮件
    XMLDocument 方法中实现post发送消息
    愿我温柔如水,坚强如钢!
    第6届蓝桥杯javaA组第7题,牌型种数,一道简单的题带来的思考
    IE兼容性问题解决方案2--css样式兼容标签
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7358170.html
Copyright © 2011-2022 走看看