hdu 3488 Tour(二分图的最优匹配)

来源:互联网 发布:淘宝差评能追评吗 编辑:程序博客网 时间:2024/06/12 22:38

 明显一个裸的二分图的最小权匹配。

第一次是因为没注意两点之间有多条边,第二次用静态链表写错是在计算t的值的时候 与最大权匹配计算t的值一样了。。 忘记取反了

 

代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 222#define maxm 33333struct node{int next, y, c;}edge[maxm];bool visx[maxn], visy[maxn];int match[maxn], lx[maxn], ly[maxn], head[maxn];int n, m, d;void add(int x, int y, int w, int tot){edge[tot].next= head[x];edge[tot].y= y;edge[tot].c= w;head[x]= tot;}void init(){memset(match, -1, sizeof(match));memset(head, -1, sizeof(head));scanf("%d %d",&n,&m);for(int i= 1; i<= m; i++){int x, y, w;scanf("%d %d %d",&x, &y, &w);add(x, y, w, i);}for(int i= 1; i<= n; i++){lx[i]= 11111;ly[i]= 0;for(int j= head[i]; j!= -1; j= edge[j].next)lx[i]= min(lx[i], edge[j].c);}}bool dfs(int u){visx[u]= true;for(int i= head[u]; i!= -1; i= edge[i].next)if(!visy[ edge[i].y ]){int t= -(lx[u]+ ly[ edge[i].y ]- edge[i].c);  //最小权匹配时这里取反 if(t== 0){visy[ edge[i].y ]= 1;if(match[ edge[i].y ]== -1 || dfs(match[ edge[i].y ])){match[ edge[i].y ]= u;return true;}}else if(t> 0)d= min(d, t);}return false;}int main(){int T;scanf("%d",&T);while(T--){init();int ans= 0;for(int i= 1; i<= n; i++){memset(visx, false, sizeof(visx));memset(visy, false, sizeof(visy));d= 1<< 30;while(!dfs(i)){for(int j= 1; j<= n; j++){if(visx[j]) lx[j]+= d;if(visy[j])ly[j]-= d;}memset(visx, false, sizeof(visx));memset(visy, false, sizeof(visy));}}for(int i= 1; i<= n; i++)ans+= lx[i]+ ly[i];printf("%d\n",ans);}return 0;}


 

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 222int map[maxn][maxn];bool visx[maxn], visy[maxn];int match[maxn], lx[maxn], ly[maxn];int n, m, d;void init(){    memset(match, -1, sizeof(match));    scanf("%d %d",&n,&m);    for(int i= 1; i<= n; i++)        for(int j= 1; j<= n; j++)            map[i][j]= 11111;    for(int i= 1; i<= m; i++)    {            int x, y, w;        scanf("%d %d %d",&x, &y, &w);        map[x][y]= min(map[x][y], w);    }    for(int i= 1; i<= n; i++)    {        lx[i]= 11111;        ly[i]= 0;        for(int j= 1; j<= n; j++)            lx[i]= min(lx[i], map[i][j]);    }    }bool dfs(int u){    visx[u]= 1;    for(int i= 1; i<= n; i++)        if(!visy[i] && map[u][i]!= 11111 && i!= u)        {            int t= -(lx[u]+ ly[i]- map[u][i]);            if(t== 0)            {                visy[i]= 1;                if(match[i]== -1 || dfs(match[i]))                {                    match[i]= u;                    return true;                }            }            else if(t> 0)                d= min(d, t);        }    return false;    }int main(){    int T;    scanf("%d",&T);    while(T--)    {        init();        int ans= 0;        for(int i= 1; i<= n; i++)            {            memset(visx, false, sizeof(visx));            memset(visy, false, sizeof(visy));            d= 1<< 30;            while(!dfs(i))            {                for(int j= 1; j<= n; j++)                {                    if(visx[j]) lx[j]+= d;                    if(visy[j]) ly[j]-= d;                }                memset(visx, false, sizeof(visx));                memset(visy, false, sizeof(visy));            }        }        for(int i= 1; i<= n; i++)            ans+= lx[i]+ ly[i];        printf("%d\n",ans);                    }    return 0;    }

0 0