hdu 2813 One fihgt one(trie树+KM算法)
来源:互联网 发布:双系统linux安装教程 编辑:程序博客网 时间:2024/04/30 19:06
小记:记得这题之前肯定有做过一次,不过那时候肯定没怎么用心做,所以现在没啥印象,然后刚好这题放在trie树的题里,直接用trie树搞了
思路:这题一看就是KM算法的应用,KM算法求边权最大的最佳匹配,这里求得是疲劳值最小的,那么将值反一下即可。最后再反过来就是答案了
但是名字是字符串的,那么必须转化过来,然后用邻接矩阵存下图,再套KM模板即可
这里我转化是用trie树的,因为名字大小写都有,所以每次trie树要保证大小写都能存入树中,
搞定好转化之后,套入kM模板,直接1a
代码:
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <map>#include <set>#include <vector>#include <stack>#include <queue>#include <algorithm>using namespace std;#define mst(a,b) memset(a,b,sizeof(a))#define eps 10e-8const int MAX_ = 210;const int MAX = 60;const int N = 500010;const int INF = (1<<30);typedef struct Node{ int isStr; //int num; struct Node *next[MAX]; Node():isStr(-1){ memset(next, NULL, sizeof(next)); } ~Node(){ for(int i = 0;i < MAX; ++i) if(next[i] != NULL) delete next[i]; }}TrieNode,*Trie;Trie root , root1;char s[MAX_], str[MAX_];int l[MAX_],r[MAX_], ln[MAX_],rn[MAX_];int link[MAX_], mp[MAX_][MAX_];int n, m;void Insert(bool flag, char *s, int num){ TrieNode *p; if(flag)p = root; else p = root1; while(*s){ if(p ->next[*s-'A'] == NULL){ p ->next[*s-'A'] = new TrieNode; } p = p ->next[*s-'A']; s++; } p->isStr = num;}int find(bool flag, char *s){ int i = 0; TrieNode *p; if(flag)p=root;else p = root1; while(*s){ if(p->next[*s-'A'] == NULL)return -1; p = p->next[*s-'A']; s++; } return p->isStr;}void init(){ memset(link,-1,sizeof(link)); memset(rn,0,sizeof(rn)); for(int i = 0; i < n; i++){ ln[i] = -INF; for(int j = 0; j < m; j++){ ln[i] = max(ln[i],mp[i][j]); } }}int dfs(int k) { l[k] = 1; for(int i = 0; i < m; i++) { if(!r[i]&&ln[k] + rn[i] == mp[k][i]) { r[i] = 1; if(link[i] == -1 || dfs(link[i])) { link[i] = k; return 1; } } } return 0;}void adjust(){ int minm = INF; for(int i = 0; i < n; i ++){ if(l[i]){ for(int j = 0; j < m; j++){ if(!r[j]){ minm = min(minm,ln[i]+rn[j]-mp[i][j]); } } } } for(int i = 0; i < n; i++){ if(l[i]){ ln[i] -= minm; } } for(int i = 0; i < m; i++){ if(r[i]){ rn[i] += minm; } }}int main() { int ans, cnt1, cnt2, len, T, k, inj, st, et; bool flag; flag = true; //ans = 0;flag = false;cnt = 0; while(scanf("%d%d%d", &n, &m, &k) != EOF){ for(int i = 0; i < n; ++i){ for(int j = 0; j < m; ++j){ mp[i][j] = -INF; } } cnt1 = cnt2 = 0; root = new TrieNode; root1 = new TrieNode; while(k -- && scanf("%s%s%d",s,str, &inj)){ st = find(true,s); if(st == -1){ st = cnt1++; Insert(true, s, st); } et = find(false, str); if(et == -1){ et = cnt2++; Insert(false, str, et); } mp[st][et] = -inj; } init(); for(int i = 0; i < n; i++){ while(1){ mst(l,0); mst(r,0); if(dfs(i))break; else adjust(); } } ans = 0; for(int i = 0; i < m; i++){ if(link[i] > -1) ans += mp[link[i]][i]; } printf("%d\n",-ans); delete root; delete root1; }}
0 0
- hdu 2813 One fihgt one(trie树+KM算法)
- HDU 2813 One fihgt one(KM算法)
- hdu 2813 One fihgt one【KM+STLmap】
- HDU 2813 One fihgt one KM水题
- HDU 2813 One fihgt one(KM最大匹配)
- HDU 2813 One fihgt one(KM算法解决最小权值匹配)
- HDU 2813 One fihgt one KM小变形
- hdu 2813 One fihgt one【KM 最小匹配】
- hdu 2813 One fihgt one(二分图最小权匹配KM)
- hdu2813One fihgt one(KM)
- One fihgt one hdu 2813 map+二分图最优匹配+KM快速模板
- HDU2813One fihgt one(KM匹配)
- 2813 One fihgt one //MaxMatch
- HDU 2282 Chocolate & HDU 2813 One fihgt one
- HDU-2813 One fihgt one【二分图最优匹配】
- HDU 2813 One fihgt one map+最大匹配值
- HDOJ 2813 - One fihgt one KM求最小权最大匹配..
- hdu2813 One fihgt one (KM最小权值和)
- 国外C#开源网站一览
- nmon下载及使用方法
- Java Map遍历方式的选择
- 十六进制字符转数字
- Mac上Svn的使用
- hdu 2813 One fihgt one(trie树+KM算法)
- 原型模式 Prototype模式
- 【ST学习小组】STM32F103的CAN 通信之从控器部分
- adb server is out of date. killing... .
- 理解 Android 2D/3D 图形架构
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结(二)
- 将项目部署到tomcat上El表达式 namespace错误
- Android ListView 最基本的用法,使用SimpleCursorAdapter
- cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄的显示