博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu2813字典树+KM
阅读量:6788 次
发布时间:2019-06-26

本文共 3164 字,大约阅读时间需要 10 分钟。

整晚都耗在KM上了。。。。果然不完全理解代码模板用起来太吃力了,其中若使用取负值的时候在正常KM模板上会在中途出错,之前也没给出标准的KM模板

当然这题的字典树可以不要,而且我用的也很粗糙有很多东西还能优化,但是加深了对字典树的使用,所以说知道结构之后会非常灵活方便呀~~~

最后今天编辑一下,总结下KM算法要注意的地方,首先是边值n,m控制好,然后就是建图:

要注意的是:若图不能将图填满,则需将空白处赋值0。

若求的是最小边权,这个模板需要用一个大数减去权值来求得最小,而不能用负数。

若求的是最大边权之积,可以用取自然对数,求出结果再e^ans;

给出挫代码:

#include"iostream"#include"cstdio"#include"cstring"using namespace std;const int N=211;const int MAXN=1<<20;int n,m,t,i,x,y,c,e,j;char a[22],b[22];int lx[N],ly[N],visx[N],visy[N],slack[N],match[N],opp[N],map[N][N];struct Tree{    int num;    int count;    Tree *next[100];    Tree()    {        num=0;        count=0;        for(int i=0;i<100;i++)        {            next[i]=NULL;        }    }}* root1,* root2;int insert(Tree *p,char *s){    int i=0,tmp;    p->count++;    tmp=p->count;    while(s[i])    {        int x=s[i]-'A';        if(p->next[x]==NULL)            p->next[x]=new Tree();        p=p->next[x];        i++;    }    p->num=tmp;    return p->num;}int find(Tree *p,char *s){    int i=0,ans=0;    while(s[i])    {        int n=s[i]-'A';        if(p->next[n])        {            p=p->next[n];            ans=p->num;            i++;        }        else {return 0;}    }    return ans;}void build(){    for(i=0;i
>a>>b; x=find(root1,a); y=find(root2,b); if(x==0) { x=insert(root1,a); } if(y==0) { y=insert(root2,b); } cin>>c; map[x-1][y-1]=-c; } /*for(int i=0;i
lx[i]) lx[i]=map[i][l]; } for(z=0;z

再给出标准模板:

#include
#include
#include
#include
#include
using namespace std;#define CLR(arr, what) memset(arr, what, sizeof(arr))#define maxn 305#define INF (1<<30)-1int g[maxn][maxn];int lx[maxn],ly[maxn];int match[maxn];bool visx[maxn],visy[maxn];int slack[maxn];char matrix[maxn][maxn];int n,m,e;void build(){ map
l; map
c; char lv[25], cao[25]; int injury, num1, num2; int result; num1 = num2 = 1; result = 0; CLR(match, -1); CLR(g, 0); l.clear(); c.clear(); for(int i = 0; i < e; ++i) { scanf("%s%s%d", lv, cao, &injury); if(!l[lv]) l[lv] = num1++; if(!c[cao]) c[cao] = num2++; g[l[lv]][c[cao]] = 9999 - injury; } /*for(i=0;i
t){ slack[y]=t; } } return false;}int KM(){ memset(match,-1,sizeof(match)); memset(ly,0,sizeof(ly)); for(int i=1 ;i<=n;i++){ lx[i]=0; for(int j=1;j<=m;j++) if(g[i][j]>lx[i]) lx[i]=g[i][j]; } for(int x=1;x<=n;x++){ for(int i=1;i<=m;i++) slack[i]=INF; while(true){ memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(dfs(x)) break; int d=INF; for(int i=1;i<=m;i++){ if(!visy[i]&&d>slack[i]) d=slack[i]; } for(int i=1;i<=n;i++){ if(visx[i]) lx[i]-=d; } for(int i=1;i<=m;i++){ if(visy[i]) ly[i]+=d; else slack[i]-=d; } } } int result = 0; for(int i = 1; i <=m; i++) if(match[i]!=-1) result += g[match[i]][i]; return result;}int main(){ while(scanf("%d%d%d",&n,&m,&e)!=EOF,n){ build(); for(int i=1;i<=n;i++) { cout<

好了,今晚到这,明天再来改下,洗洗睡了

转载于:https://www.cnblogs.com/amourjun/archive/2013/04/18/5134177.html

你可能感兴趣的文章
基于Vue.js 2.0 + Vuex打造微信项目
查看>>
作业十三
查看>>
Unity3D 常用 英文单词
查看>>
Go语言标准库_输入/输出
查看>>
题目1489:计算两个矩阵的乘积
查看>>
GPU-BASED PROCEDURAL PLACEMENT IN HORIZON ZERO DAWN
查看>>
mysql中[Err] 1366 - Incorrect string value: '\xE5\x8D\x问题
查看>>
Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
查看>>
Mysql用户管理(远程连接、授权)
查看>>
Coursera机器学习编程作业Python实现(Andrew Ng)—— 2.1 Logistic Regression
查看>>
前台动态增加行,并将结果打印到XML文件
查看>>
简单回溯,最少步数
查看>>
LeetCode – Refresh – Palindrome Partitioning II
查看>>
mysql线上数据库单表超过200G的处理
查看>>
生成静态页相关
查看>>
OC中ARC forbids explicit message send of release错误
查看>>
J2SE 学习记录
查看>>
VS静态编译
查看>>
个人作业——Alpha项目测试
查看>>
laravel之laravel-admin安装
查看>>