HDU1116:Play on Words
以前做过的一道题
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;
int dr[26],dc[26],N,f[26];
bool e[26],g[26][26];
bool bfs()
{
int i;
memset(f,0,sizeof(f));
queue<int> q;
while (!q.empty()) q.pop();
for (i=0;i<26;i++)
if (e[i])
{
f[i]=true;
q.push(i);
break;
}
while (!q.empty())
{
int x=q.front();
q.pop();
for (i=0;i<26;i++)
if (g[x][i])
{
if (!f[i])
{
f[i]=true;
q.push(i);
}
}
}
for (i=0;i<26;i++)
if ((e[i]) && (!f[i])) return false;
return true;
}
int main()
{
int T,i;
scanf("%d",&T);
while (T--)
{
scanf("%d",&N);
char s[1024];
memset(g,0,sizeof(g));
memset(e,0,sizeof(e));
memset(dr,0,sizeof(dr));
memset(dc,0,sizeof(dc));
for (i=1;i<=N;i++)
{
scanf("%s",s);
int u=s[0]-'a',v=s[strlen(s)-1]-'a';
g[u][v]=true;
g[v][u]=true;
e[u]=true;
e[v]=true;
dc[u]++;
dr[v]++;
}
bool flag=bfs();
int cnt0=0,cnt1=0;
for (i=0;i<26;i++)
{
if (dr[i]-dc[i]>1 || dr[i]-dc[i]<-1) flag=false;
if (dr[i]-dc[i]==1) cnt0++;
if (dr[i]-dc[i]==-1) cnt1++;
}
if (!((cnt0==0 && cnt1==0)||(cnt0==1 && cnt1==1))) flag=false;
if (flag) printf("Ordering is possible.
");
else printf("The door cannot be opened.
");
}
return 0;
}
HDU3549:Flow Problem
Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 13708 Accepted Submission(s): 6538
Problem Description
Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
Input
The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
Output
For each test cases, you should output the maximum flow from source 1 to sink N.
Sample Input
2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
Sample Output
Case 1: 1
Case 2: 2
Author
HyperHexagon
模板题,手写了一下Edmond_Karp.
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <queue>
using namespace std;
int G[100][100], F[100][100];
int p[100];
bool f[100];
int N, M, T;
queue<int> q;
int Edmond_Karp() {
int ret = 0, u, MIN, tmp;
memset(F, 0, sizeof(F));
while (1) {
while (!q.empty()) {
q.pop();
}
MIN = 0x7FFFFFFF;
memset(f, false, sizeof(f));
q.push(1);
f[1] = true;
while (!q.empty()) {
u = q.front();
q.pop();
for (int i = 1; i <= N; i++) {
if (G[u][i] > F[u][i] && !f[i]) {
q.push(i);
p[i] = u;
f[i] = true;
}
}
}
if (!f[N]) {
break;
}
for (int i = N; i != 1; i = p[i]) {
tmp = G[p[i]][i] - F[p[i]][i];
if (tmp < MIN) {
MIN = tmp;
}
}
for (int i = N; i != 1; i = p[i]) {
F[p[i]][i] += MIN;
F[i][p[i]] -= MIN;
}
ret+=MIN;
}
return ret;
}
int main() {
int x, y, c;
scanf("%d", &T);
for (int o = 1; o <= T; o++) {
scanf("%d%d", &N, &M);
memset(G, 0, sizeof(G));
for (int i = 0; i < M; i++) {
scanf("%d%d%d", &x, &y, &c);
G[x][y] += c;
}
printf("Case %d: %d
", o, Edmond_Karp());
}
return 0;
}
HDU1532:Drainage Ditches
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15641 Accepted Submission(s): 7450
Problem Description
Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie's clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch.
Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network.
Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle.
Input
The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.
Output
For each case, output a single integer, the maximum rate at which water may emptied from the pond.
Sample Input
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
Sample Output
50
基本照搬上道题.
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <queue>
using namespace std;
int F[205][205];
int p[205];
bool f[205];
int N, M, T;
queue<int> q;
int Edmond_Karp() {
int ret = 0, u, MIN;
while (1) {
while (!q.empty()) {
q.pop();
}
MIN = 0x7FFFFFFF;
memset(f, false, sizeof(f));
q.push(1);
f[1] = true;
while (!q.empty()) {
u = q.front();
q.pop();
for (int i = 1; i <= N; i++) {
if (F[u][i] && !f[i]) {
q.push(i);
p[i] = u;
f[i] = true;
}
}
}
if (!f[N]) {
break;
}
for (int i = N; i != 1; i = p[i]) {
if (F[p[i]][i] < MIN) {
MIN = F[p[i]][i];
}
}
for (int i = N; i != 1; i = p[i]) {
F[p[i]][i] -= MIN;
F[i][p[i]] += MIN;
}
ret += MIN;
}
return ret;
}
int main() {
int x, y, c;
while (scanf("%d%d", &M, &N) != EOF) {
memset(F, 0, sizeof(F));
for (int i = 0; i < M; i++) {
scanf("%d%d%d", &x, &y, &c);
F[x][y] += c;
}
printf("%d
", Edmond_Karp());
}
return 0;
}
HDU3572:Task Schedule
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7528 Accepted Submission(s): 2328
Problem Description
Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
Input
On the first line comes an integer T(T<=20), indicating the number of test cases.
You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible schedule every task that can be finished will be done before or at its end day.
Output
For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.
Print a blank line after each test case.
Sample Input
2
4 3
1 3 5
1 1 4
2 3 7
3 5 9
2 2
2 1 3
1 2 2
Sample Output
Case 1: Yes
Case 2: Yes
这题略叼,首先构建一个流量网络,YY出来一个超级源点和一个超级汇点,并把每个工作和每一天作为节点加入。从超级源点出发创建n条弧指向n个工作,容量为其所需时间。从每个工作出发各创建相应数量的弧指向其对应的时间区间上的每个节点,容量为1。从每个时间节点出发创建一条弧指向超级汇点,容量为机器数。判断最大流是否等于所有的工作所需时间之和,若相等则可以按时完成,否则不能。
这题用EK不行了,要用SAP。
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <queue>
using namespace std;
const int SAP_INF = 0x7FFFFFFF;
template <int N, int M> class ISAP {
public:
int top, edgeCnt;
int d[N], pre[N], cur[N], gap[N];
struct Vertex {
int head;
} V[N];
struct Edge {
int v, next;
int c, f;
} E[M];
void init() {
memset(V, -1, sizeof(V));
top = 0;
edgeCnt = 0;
}
void add_edge(int u, int v, int c) {
E[top].v = v;
E[top].c = c;
E[top].f = 0;
E[top].next = V[u].head;
V[u].head = top++;
}
void add(int u, int v, int c) {
add_edge(u, v, c);
add_edge(v, u, 0);
edgeCnt++;
}
void set_d(int t) {
queue<int> Q;
memset(d, -1, sizeof(d));
memset(gap, 0, sizeof(gap));
d[t] = 0;
Q.push(t);
while (!Q.empty()) {
int v = Q.front();
Q.pop();
++gap[d[v]];
for (int i = V[v].head; ~i; i = E[i].next) {
int u = E[i].v;
if (d[u] == -1) {
d[u] = d[v] + 1;
Q.push(u);
}
}
}
}
int MaxFlow_SAP(int s, int t) {
set_d(t);
int ans = 0, u = s;
int flow = SAP_INF;
memcpy(cur, V, sizeof(V));
while (d[s] < edgeCnt) {
int &i = cur[u];
for (; ~i; i = E[i].next) {
int v = E[i].v;
if (E[i].c > E[i].f && d[u] == d[v] + 1) {
u = v;
pre[v] = i;
flow = min(flow, E[i].c - E[i].f);
if (u == t) {
while (u != s) {
int j = pre[u];
E[j].f += flow;
E[j ^ 1].f -= flow;
u = E[j ^ 1].v;
}
ans += flow;
flow = SAP_INF;
}
break;
}
}
if (i == -1) {
if (--gap[d[u]] == 0) {
break;
}
int dmin = edgeCnt - 1;
cur[u] = V[u].head;
for (int j = V[u].head; ~j; j = E[j].next)
if (E[j].c > E[j].f) {
dmin = min(dmin, d[E[j].v]);
}
d[u] = dmin + 1;
++gap[d[u]];
if (u != s) {
u = E[pre[u] ^ 1].v;
}
}
}
return ans;
}
};
ISAP<1005, 300000> Sap;
int main() {
int T, n, m, a, b, c, N, s;
scanf("%d", &T);
for (int o = 1; o <= T; o++) {
Sap.init();
s = 0;
scanf("%d%d", &n, &m);
N = n + 502;
for (int i = n + 2; i <= n + 501; i++) {
Sap.add(i, N, m);
}
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &a, &b, &c);
s += a;
Sap.add(1, i + 1, a);
for (int j = b; j <= c; j++) {
Sap.add(i + 1, n + 1 + j, 1);
}
}
printf("Case %d: %s
", o, Sap.MaxFlow_SAP(1, N) == s ? "Yes" : "No");
}
return 0;
}