解题报告 之 SOJ4429 Frog's Dice
2015-04-14 00:13
246 查看
解题报告 之
SOJ 4429 Frog's Dice
The Problem
frog has many dices:)Each dice has six surfaces and there is a lowercase letter on each surfaces.
Now, frog want to put these dices in a row so that the letters on the upper faces could form a certain word.
She can put these dices in any order but each dice can only be used once.
Please tell frog whether she could make that thing happen.?
Input
The first line of input is the number of test case.Then for each case:
The first line is a number n(1 <= n <= 1000), indicating the number of dices.
Then there are n lines, each line has six lowercase letters(separated by space), indicating the letters on a dice.
The last line has n lowercase letters, indicating frog's special word.
Output
For each case, print one line:If frog can get her special word, print "Cong, frog!"(without quotation);
else print "Sorry, frog."
Example Input
2 3 s c u a c m a b c d e f a b c d e f scu 4 a e c f a c d z b g f a p r j a a a h e t g o a frog
Example Output
Sorry, frog. Cong, frog!
题目大意:Frog神有n个骰子,每个骰子每一面分别有一个字母,然后给你一个字符串,问你能不能用这些骰子拼出这个字符串,每个骰子使用小于等于1次。
分析:明显的二分图匹配,于是乎解决办法就是,设立n个骰子节点,26个字母节点,将超级源点与所有骰子节点连接,负载为INF。将第i个骰子与它每一面对应的字母连上一条负载为1的边。然后数一下字符串里每种字母出现了k次,就在对应的字母节点连一条负载为k的边到超级汇点。
最后看从超级源点到超级汇点的最大流是否==字符串长度l,如果等于则可以组成。那么就上代码了。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<string> using namespace std; const int MAXN = 1510; const int MAXM = 200010; const int INF = 0x3f3f3f3f; struct Edge { int to, next; int cap; }; Edge edge[MAXM]; int n; int cnt, src, des; //cnt表示一共有几条边 int head[MAXN]; //head[i]表示节点i的第一条边的编号 int level[MAXN]; int times[26]; void addedge(int from, int to, int cap) { edge[cnt].to = to; edge[cnt].cap = cap; edge[cnt].next = head[from]; head[from] = cnt++; edge[cnt].to = from; edge[cnt].cap = 0; edge[cnt].next = head[to]; head[to] = cnt++; } int bfs() { queue<int> q; while (!q.empty()) q.pop(); memset(level, -1, sizeof(level)); level[src] = 0; //源点的深度为0 q.push(src); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > 0 && level[v] == -1) //该边未访问过且该边有流量 { level[v] = level[u] + 1; q.push(v); } } } return level[des] != -1; //返回是否还存在连通路 } int dfs(int u, int f) { if (u == des) return f; int tem; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > 0 && level[v] == level[u] + 1) { tem = dfs(v, min(f, edge[i].cap)); if (tem > 0) { edge[i].cap -= tem; edge[i ^ 1].cap += tem; //更新边与反向边的流量 return tem; } } } level[u] = -1; //表示已经走过该点 return 0; } int Dinic() { int ans = 0, tem; while (bfs())//如果还存在连通路 { while (tem = dfs(src, INF)) //一直试图寻找增广路 { ans += tem; } } return ans; } int main() { int kase; scanf("%d", &kase); while (kase--) { char ch; scanf("%d", &n); cnt = 0; memset(head, -1, sizeof(head)); memset(times, 0, sizeof(times)); int f, d; src = n+26, des = src+1; for (int i = 0; i < n; i++) { addedge(src, i, 1); } for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) { cin >> ch; int num = ch - 'a'; addedge(i, n+num, 1); } } string str; cin >> str; int l = str.length(); for (int i = 0; i < l; i++) { times[str[i] - 'a']++; } for (int i = 0; i < 26; i++) { if(times[i]) addedge(n + i, des, times[i]); } if (str.length() == Dinic()) cout << "Cong, frog!" << endl; else cout << "Sorry, frog." << endl; } return 0; }
就是这样,反正校赛还是靠大大~~
相关文章推荐
- POJ-2262-Goldbach's Conjecture 解题报告
- K - Goldbach's Conjecture解题报告(陈渊)
- HDOJ-1397-Goldbach's Conjecture 解题报告
- 解题报告:POJ 2965 The Pilots Brothers' refrigerator 两种做法
- uva 10985 Rings'n'Ropes 解题报告
- HDOJ-1164-Eddy's research I 解题报告
- 快速排序浅谈——(解题报告)HDU1157和POJ2388---Who's in the Middle
- ZYB's Game解题报告
- Hdu 1009 FatMouse' Trade解题报告
- FatMouse' Trade 解题报告
- UVa 152 - Tree's a Crowd解题报告
- [cf193c]Students' Revenge解题报告
- 2909 Goldbach's Conjecture 解题报告
- HDOJ-1160-FatMouse's Speed 解题报告
- SCU 4429 frog's dice (二分匹配 or 网络流)
- ACdream 1203 - KIDx's Triangle(解题报告)
- K - Goldbach's Conjecture解题报告
- YT02-简单数学课后题-1001 FatMouse' Trade-(5.31日-烟台大学ACM预备队解题报告)
- USACO Betsy's Tour 解题报告
- HOJ 12058 Judges' Time Calculation 解题报告