2012年10月17日 星期三

uva 10048 - Audiophobia



  Problem B: Audiophobia 

Consider yourself lucky! Consider yourself lucky to be still breathing and having fun participating in this contest. But we apprehend that many of your descendants may not have this luxury. For, as you know, we are the dwellers of one of the most polluted cities on earth. Pollution is everywhere, both in the environment and in society and our lack of consciousness is simply aggravating the situation.However, for the time being, we will consider only one type of pollution ­- the sound pollution. The loudness or intensity level of sound is usually measured in decibels and sound having intensity level 130 decibels or higher is considered painful. The intensity level of normal conversation is 60­65 decibels and that of heavy traffic is 70­80 decibels.
Consider the following city map where the edges refer to streets and the nodes refer to crossings. The integer on each edge is the average intensity level of sound (in decibels) in the corresponding street.

To get from crossing A to crossing G you may follow the following path: A­C­F­G. In that case you must be capable of tolerating sound intensity as high as 140 decibels. For the paths A­B­E­G, A­B­D­G and A­C­F­D­G you must tolerate respectively 90, 120 and 80 decibels of sound intensity. There are other paths, too. However, it is clear that A­C­F­D­G is the most comfortable path since it does not demand you to tolerate more than 80 decibels.
In this problem, given a city map you are required to determine the minimum sound intensity level you must be able to tolerate in order to get from a given crossing to another.

Input 

The input may contain multiple test cases.
The first line of each test case contains three integers $C (\le 100)$, $S (\le
1000)$ and $Q (\le 10000)$ where C indicates the number of crossings (crossings are numbered using distinct integers ranging from 1 to C), S represents the number of streets and Q is the number of queries.
Each of the next S lines contains three integers: c1, c2 and d indicating that the average sound intensity level on the street connecting the crossings c1 and c2 ( $c_1 \ne c_2$) is d decibels.
Each of the next Q lines contains two integers c1 and c2 ( $c_1 \ne c_2$) asking for the minimum sound intensity level you must be able to tolerate in order to get from crossing c1 to crossing c2.
The input will terminate with three zeros form C, S and Q.

Output 

For each test case in the input first output the test case number (starting from 1) as shown in the sample output. Then for each query in the input print a line giving the minimum sound intensity level (in decibels) you must be able to tolerate in order to get from the first to the second crossing in the query. If there exists no path between them just print the line ``no path".
Print a blank line between two consecutive test cases.

Sample Input 

7 9 3
1 2 50
1 3 60
2 4 120
2 5 90
3 6 50
4 6 80
4 7 70
5 7 40
6 7 140
1 7
2 6
6 2
7 6 3
1 2 50
1 3 60
2 4 120
3 6 50
4 6 80
5 7 40
7 5
1 7
2 4
0 0 0

Sample Output 

Case #1
80
60
60
 
Case #2
40
no path
80



Miguel Revilla
2000-12-26

1.minimum spanning tree
2. DFS on each vertex to find distance, O(N^2)
#include<stdio.h>
#include<cstring>
#include<vector>
#include<queue>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
#define MAXN 100
#define MAXM 1000
#define MAXQ 10000
#define INF 2139062143
using namespace std;

int N,M,Q,e,cases=1;
int v1[MAXM],v2[MAXM],w[MAXM],p[MAXN],mate[MAXN][2],query[MAXQ][2],dis[MAXN][MAXN];
bool trav[MAXN];
vector<pair<int,int> >match[MAXN];
struct Node{
Node(int a,int b,int c):v1(a),v2(b),dis(c){}
bool operator <(const Node b)const {return dis>b.dis;}
int v1,v2,dis;
};
void addedge(int a,int b,int c){
if(DBG)printf("addedge %d %d\n",a,b);
v1[e]=a,v2[e]=b,w[e]=c,e++;
}
int find(int v){
if(p[v]==v)return v;
return p[v]=find(p[v]);
}
void unit(int from,int to){
p[find(from)]=p[find(to)];
}
void DFS(int root,int c,int m){
trav[c]=1;
int mm=m,b;
if(DBG)printf("DFS root %d c %d m %d\n",root,c,m);
rep(i,match[c].size()){
if(!trav[match[c][i].first]){
b=match[c][i].first;
if(match[c][i].second>m)mm=match[c][i].second;
dis[root][b]=dis[b][root]=mm;
DFS(root,b,mm);
mm=m;
}
}
trav[c]=0;
}
void ans(){
int a,b,c,d=0;
priority_queue<Node>q;
rep(i,e)q.push(Node(v1[i],v2[i],w[i]));
rep(i,N)p[i]=i,match[i].clear();
while(q.size()&&d<N-1){
a=q.top().v1,b=q.top().v2,c=q.top().dis,q.pop();
if(DBG)printf("a b %d %d\n",a,b);
if(find(a)!=find(b))unit(a,b),
match[a].push_back(make_pair(b,c)),match[b].push_back(make_pair(a,c)),d++;
}
memset(dis,0x7f,sizeof(dis));
rep(i,N){memset(trav,0,sizeof(trav));DFS(i,i,0);}
printf("Case #%d\n",cases++);
rep(i,Q)if(dis[query[i][0]-1][query[i][1]-1]==INF)printf("no path\n");
else printf("%d\n",dis[query[i][0]-1][query[i][1]-1]);
}
int main(){
int a,b,c;
bool ll=0;
while(scanf("%d%d%d",&N,&M,&Q)==3){
if(N+M+Q==0)break;
e=0;
rep(i,M)scanf("%d%d%d",&a,&b,&c),a--,b--,addedge(a,b,c);
rep(i,Q)scanf("%d%d",&query[i][0],&query[i][1]);
if(ll)printf("\n");ll=1;
ans();
}
return 0;
}
alternative: Floyd-Warshall algorithm, O(N^3)
#include<stdio.h>
#include<string.h>
#include<iostream>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define PI 3.141592653589793
#define INF 2147483647
#define DBG 0
using namespace std;

typedef long long ll;
int cases=1,N;
int dis[100][100];
void allpairs(){
ll c;
rep(k,N){
rep(i,N)
rep(j,N){
c=max(dis[i][k],dis[k][j]);
if(c<dis[i][j])dis[i][j]=c;
}
//if(DBG)rep(i,N){rep(j,N)printf("(%d)%f ",k,dis[i][j]);printf("\n");}
}
}
int main(){
int a,b,c,d,e;
bool ll=0;
while(cin>>N>>b>>c){
if(N==0&&b==0&&c==0)break;
rep(i,100)rep(j,100)if(i!=j)dis[i][j]=INF;
rep(i,b)cin>>a>>d>>e,dis[a-1][d-1]=dis[d-1][a-1]=e;
if(ll)printf("\n");ll=1;
allpairs();
printf("Case #%d\n",cases++);
rep(i,c){
cin>>a>>d;
if(dis[a-1][d-1]<INF)printf("%d\n",dis[a-1][d-1]);
else printf("no path\n");
}
}
}

11747 - Heavy Cycle Edges


Problem F: Heavy Cycle Edges

Given an undirected graph with edge weights, a minimum spanning tree is a subset of edges of minimum total weight such that any two nodes are connected by some path containing only these edges. A popular algorithm for finding the minimum spanning tree T in a graph proceeds as follows:
  • let T be initially empty
  • consider the edges e1, ..., em in increasing order of weight
    • add ei to T if the endpoints of ei are not connected by a path in T
An alternative algorithm is the following:
  • let T be initially the set of all edges
  • while there is some cycle C in T
    • remove edge e from T where e has the heaviest weight in C
Your task is to implement a function related to this algorithm. Given an undirected graph G with edge weights, your task is to output all edges that are the heaviest edge in some cycle of G.

Input Format

The first input of each case begins with integers n and m with 1 ≤ n ≤ 1,000 and 0 ≤ m ≤ 25,000 where n is the number of nodes and m is the number of edges in the graph. Following this are m lines containing three integers u, v, and w describing a weight w edge connecting nodes u and v where 0 ≤ u, v < n and 0 ≤ w < 231. Input is terminated with a line containing n = m = 0; this case should not be processed. You may assume no two edges have the same weight and no two nodes are directly connected by more than one edge.

Output Format

Output for an input case consists of a single line containing the weights of all edges that are the heaviest edge in some cycle of the input graph. These weights should appear in increasing order and consecutive weights should be separated by a space. If there are no cycles in the graph then output the text forest instead of numbers.

Sample Input

3 3
0 1 1
1 2 2
2 0 3
4 5
0 1 1
1 2 2
2 3 3
3 1 4
0 2 0
3 1
0 1 1
0 0

Sample Output

3
2 4
forest

Zachary Friggstad
not
Used with an auxiliary verb or “be” to form the negative
Tip: Didn't want this definition pop-up? Try setting a trigger key in Extension Options.


minimum spanning tree - kruskal
#include<stdio.h>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
#define MAXM 25000
#define MAXN 1000
using namespace std;

int N,M,e;
int v1[MAXM],v2[MAXM],w[MAXM],p[MAXN];
struct Node{
Node(int a,int b,int c):v1(a),v2(b),dis(c){}
bool operator <(const Node b)const {return dis>b.dis;}
int v1,v2,dis;
};
void addedge(int a,int b,int c){
v1[e]=a,v2[e]=b,w[e]=c,e++;
}
int find(int v){
if(p[v]==v)return v;
return p[v]=find(p[v]);
}
void unit(int from,int to){
p[find(from)]=p[find(to)];
}
void ans(){
int a,b,c,d=0,sum=0;
vector<int>res;
priority_queue<Node>q;
rep(i,e)q.push(Node(v1[i],v2[i],w[i]));
rep(i,N)p[i]=i;
while(q.size()){
a=q.top().v1,b=q.top().v2,c=q.top().dis,q.pop();
if(DBG)printf("a b %d %d\n",a,b);
if(find(a)!=find(b))unit(a,b),sum+=c,d++;
else res.push_back(c);
}
sort(res.begin(),res.end());
bool ll=0;
if(res.size())rep(i,res.size()){if(ll)printf(" ");ll=1;printf("%d",res[i]);}
else printf("forest");
printf("\n");
}
int main(){
int a,b,c;
while(scanf("%d%d",&N,&M)==2){
e=0;
if(N==0&&M==0)break;
rep(i,M)scanf("%d%d%d",&a,&b,&c),addedge(a,b,c);
ans();
}
return 0;
}

uva 11631 - Dark roads


2009/2010 ACM International Collegiate Programming Contest
University of Ulm Local Contest

Problem D: Dark roads

Economic times these days are tough, even in Byteland. To reduce the operating costs, the government of Byteland has decided to optimize the road lighting. Till now every road was illuminated all night long, which costs 1 Bytelandian Dollar per meter and day. To save money, they decided to no longer illuminate every road, but to switch off the road lighting of some streets. To make sure that the inhabitants of Byteland still feel safe, they want to optimize the lighting in such a way, that after darkening some streets at night, there will still be at least one illuminated path from every junction in Byteland to every other junction.
What is the maximum daily amount of money the government of Byteland can save, without making their inhabitants feel unsafe?

Input Specification

The input file contains several test cases. Each test case starts with two numbers m and n, the number of junctions in Byteland and the number of roads in Byteland, respectively. Input is terminated by m=n=0. Otherwise, 1 ≤ m ≤ 200000and m-1 ≤ n ≤ 200000. Then follow n integer triples x, y, z specifying that there will be a bidirectional road between x andy with length z meters (0 ≤ x, y < m and x ≠ y). The graph specified by each test case is connected. The total length of all roads in each test case is less than 231.

Output Specification

For each test case print one line containing the maximum daily amount the government can save.

Sample Input

7 11
0 1 7
0 3 5
1 2 8
1 3 9
1 4 7
2 4 5
3 4 15
3 5 6
4 5 8
4 6 9
5 6 11
0 0

Sample Output

51


minimum spanning tree - kruskal
#include<stdio.h>
#include<cstring>
#include<queue>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
#define MAXM 200000
using namespace std;

int N,M,D,e;
int v1[MAXM],v2[MAXM],w[MAXM],p[MAXM];
struct Node{
Node(int a,int b,int c):v1(a),v2(b),dis(c){}
bool operator <(const Node b)const {return dis>b.dis;}
int v1,v2,dis;
};
void addedge(int a,int b,int c){
v1[e]=a,v2[e]=b,w[e]=c,e++;
}
int find(int v){
if(p[v]==v)return v;
return p[v]=find(p[v]);
}
void unit(int from,int to){
p[find(from)]=p[find(to)];
}
void ans(){
int a,b,c,d=0,sum=0;
priority_queue<Node>q;
rep(i,e)q.push(Node(v1[i],v2[i],w[i]));
rep(i,N)p[i]=i;
while(d<N-1){
a=q.top().v1,b=q.top().v2,c=q.top().dis,q.pop();
if(DBG)printf("a b %d %d\n",a,b);
if(find(a)!=find(b))unit(a,b),sum+=c,d++;
}
printf("%d\n",D-sum);
}
int main(){
int a,b,c;
while(scanf("%d%d",&N,&M)==2){
D=0,e=0;
if(N==0&&M==0)break;
rep(i,M)scanf("%d%d%d",&a,&b,&c),addedge(a,b,c),D+=c;
ans();
}
return 0;
}

uva 11228 - Transportation system


J. Transportation system

Time limit: 2s

In the country of Graphland, there are many cities but no roads. The federal government wants to change this situation and plans to build roads and railroads such that all the cities in the country are connected through this new transportation system. To make the new system more efficient, Graphland will build only roads between cities within the same state and will use railroads to connect cities that are in different states. For the purposes of this problem, consider that if the distance between any two cities is at most r then they are in the same state. To minimize the costs of building the roads and railroads, the government also wants to build only the minimum necessary extension of roads and railroads such that there is a path between any pair of cities in the entire country. You've been hired to determine what's the optimum transportation network system that Graphland must build.
The first line of the input contains the number of test cases that follow. On the first line of each test case, there will be two integers, n (1 ≤ n ≤ 1000), the number of cities that comprise Graphland, and r (0 ≤ r ≤ 40000), the threshold value to determine if two cities are in the same state. On the following n lines, there will be a list of x-y (-10000 ≤ x, y ≤ 10000) integer coordinates in the plan for each city in Graphland. Your program must output the number of states in Graphland and the minimum extension (rounded to the nearest integer) of both roads and railroads that must be built to satisfy the conditions of the project.

Input

The first line of input gives the number of cases, T (1 ≤ T ≤ 20). T test cases follow. On the first line of each test case, there will be two integers, n (1 ≤ n ≤ 1000), the number of cities that comprise Graphland, and r (0 ≤ r ≤ 40000), the threshold value to determine if two cities are in the same state. On the following n lines, there will be a list of x-y (-10000 ≤ x, y ≤ 10000) integer coordinates in the plan for each city in Graphland.

Output

The output is comprised of one line for each input data set. The line identifies the data set with a number (starting from one and incrementing at each new data set), followed by the number of states in Graphland and the minimum extension (rounded to the nearest integer) of both roads and railroads that must be built to satisfy the conditions of the project.

Sample input

3
3 100
0 0
1 0
2 0
3 1
0 0
100 0
200 0
4 20
0 0
40 30
30 30
10 10

Sample output

Case #1: 1 2 0
Case #2: 3 0 200
Case #3: 2 24 28

Problem setter: Herbert de Melo Duarte.
Universidade Federal do Rio Grande do Norte Qualifying Contest IV, June 9th, 2007.


minimum spanning tree - Kruskal
#include<stdio.h>
#include<cstring>
#include<queue>
#include<cmath>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
#define MAXN 1000
using namespace std;

int N,cases=1,C,R;
int cor[MAXN][2],p[MAXN];
double dis[MAXN][MAXN];
bool isp[MAXN];
vector<int>group[MAXN],sn;
struct Node{
Node(double a,int b,int c):dis(a),v1(b),v2(c){}
bool operator <(const Node b)const {return dis>b.dis;}
int v1,v2;
double dis;
};
int find(int v){
if(p[v]==v)return v;
return p[v]=find(p[v]);
}
void unit(int from,int to){
p[find(from)]=p[find(to)];
}
double getD(int a,int b){
return sqrt(pow(double(cor[a][0]-cor[b][0]),2)+pow(double(cor[a][1]-cor[b][1]),2));
}
void getSts(){
sn.clear();rep(i,N)group[i].clear();memset(isp,0,sizeof(isp));
rep(i,N)p[i]=i;
rep(i,N)REP(j,i+1,N){
dis[i][j]=dis[j][i]=getD(i,j);
if(find(i)!=find(j)&&dis[i][j]<R)unit(i,j),C--;
}
int a;
rep(i,N){
a=find(i);
group[a].push_back(i);
if(!isp[a])isp[a]=1,sn.push_back(a);
}
}
void add(int a,int b,double &c){
c=1e300;
rep(i,group[a].size())
rep(j,group[b].size())
if(c>dis[group[a][i]][group[b][j]])
c=dis[group[a][i]][group[b][j]];
}
void ans(){
int a,b,c;
C=N,getSts();
if(DBG)printf("state: %d\n",C);
priority_queue<Node>q2;
double d,s1=0,s2=0;
int cnt;
rep(i,N)p[i]=i;
rep(k,N){ //same state
if(group[k].size()){
cnt=0;
priority_queue<Node>q;
rep(i,group[k].size())REP(j,i+1,group[k].size()){
a=group[k][i],b=group[k][j],cnt++;
if(DBG&&!cnt%100)printf("push %d %d: %f\n",a,b,dis[a][b]);
q.push(Node(dis[a][b],a,b));
}
if(DBG)printf("done: size %d\n",group[k].size());
c=0;
while(c<group[k].size()-1){
a=q.top().v1,b=q.top().v2,d=q.top().dis,q.pop();
//if(DBG)printf("edge %d %d: %f\n",a,b,dis);
if(find(a)!=find(b)){
unit(a,b),s1+=d,c++;
if(DBG)printf("c %d\n",c);}
}
}
}
rep(i,N)p[i]=i;
if(DBG)printf("dis: %f\n",s1);
rep(i,sn.size())REP(j,i+1,sn.size()){ //diff state
add(sn[i],sn[j],d);
q2.push(Node(d,i,j));
}
c=0;
while(c<C-1){
a=q2.top().v1,b=q2.top().v2,d=q2.top().dis,q2.pop();
if(DBG)printf("set %d %d: %f\n",a,b,dis);
if(find(a)!=find(b))unit(a,b),s2+=d,c++;
}
printf("Case #%d: %d %d %d\n",cases++,C,int(s1+0.5),int(s2+0.5));
}
int main(){
int n;
scanf("%d",&n);
rep(i,n){
scanf("%d%d",&N,&R);
rep(i,N)scanf("%d%d",&cor[i][0],&cor[i][1]);
ans();
}
return 0;
}

uva 11159 - Factors and Multiples

Next Generation Contest 3
Factors and Multiples


You will be given two sets of integers. Let�s call them set A and set B. Set A contains n elements and set B contains melements. You have to remove k1 elements from set A and k2 elements from set B so that of the remaining values no integer in set B is a multiple of any integer in set A. k1 should be in the range [0,n] and k2 in the range [0,m].
You have to find the value of (k1+k2) such that (k1+k2) is as low as possible.

P is a multiple of Q if there is some integer K such that P = K * Q.


Suppose set A is {2,3,4,5} and set B is {6,7,8,9}. By removing 2 and 3 from A and 8 from B, we get the sets{4,5} and {6,7,9}. Here none of the integers 6, 7 or 9 is a multiple of 4 or 5.

So for this case the answer is 3 (2 from set A and 1 from set B).

Input

The first line of input is an integer T(T<50 span="span"> that determine the number of test cases. Each case consists of two lines. The first line starts with n followed by n integers. The second line starts with m followed by m integers. Both n and m will be in the range [1,100]. All the elements of the two sets will fit in 32 bit signed integer.

Output

For each case, output the case number followed by the answer.

Sample Input
Output for Sample Input
2
4 2 3 4 5
4 6 7 8 9
3 100 200 300
1 150
Case 1: 3
Case 2: 0

Problem Setter: Sohel Hafiz
Special Thanks: Jane Alam Jan

bipartite graph - minimum vertex cover = maximum cardinality in bipartite matching
note: integers contain zero.
#include<stdio.h>
#include<cstring>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
#define MAXN 200
#define MAXM 20000

int N,M,e;
int v[MAXM],next[MAXM],head[MAXN],num[MAXN];
int xM[MAXN],yM[MAXN],cases=1;
bool trav[MAXN];
void addedge(int a,int b){
    v[e]=b,next[e]=head[a],head[a]=e,e++;
    v[e]=a,next[e]=head[b],head[b]=e,e++;
}
bool search(int b){
    for(int a=head[b];a>=0;a=next[a]){
        if(!trav[v[a]]){
            trav[v[a]]=1;
            if(yM[v[a]]<0||search(yM[v[a]])){
                xM[b]=v[a],yM[v[a]]=b;
                return 1;
            }
        }
    }
    return 0;
}
void ans(){
    int res=0;
    memset(xM,-1,sizeof(xM));
    memset(yM,-1,sizeof(yM));
    rep(i,N){
        if(xM[i]<0){
            memset(trav,0,sizeof(trav));
            if(search(i)){
                if(DBG)printf("search: %d %d\n",num[i],num[xM[i]]);
                res++;
            }
        }
    }
    printf("Case %d: %d\n",cases++,res);
}
void build(){
    rep(j,M)rep(i,N)
        if(num[j+N]==0)addedge(j+N,i);
        else if(num[i]>0&&num[j+N]%num[i]==0)addedge(j+N,i);
}
int main(){
   int n;
   scanf("%d",&n);
   rep(i,n){
        e=0,memset(head,-1,sizeof(head));
        scanf("%d",&N);
        rep(i,N)scanf("%d",&num[i]);
        scanf("%d",&M);
        rep(i,M)scanf("%d",&num[i+N]);
        build();
        ans();
    }
   return 0;
}

uva 11138 - Nuts 'n' Bolts


Problem J

Nuts 'n' Bolts

One afternoon your cell phone rings; it's your cousin Jimmy.
"Hi Cuz," he says, "I need your help and I need it fast. I'm in the middle of a programming contest and however hard I try, I can't get one problem to finish within the two second time limit."
"Hmm... well..., isn't that a bit illegal?", you try to say to him. But he rattles on.
"I just snook out of the contest room and managed to send you my code and the sample I/O by email", he continues without pausing. "I will check my mail again in an hour, so please make it work for me."
"What about the problem description?", you ask.
"Can't do", he says, "Zoroman the Head Judge is already on my tail, so I got to go. Bye, ... and, eh, thanks."

Are you going to help him?

Jimmy's Code

#include 

#define MAX_BOLTS 500
#define MAX_NUTS  500

/* global copy of the input data */
int nuts,bolts;
int fits[MAX_BOLTS][MAX_NUTS];

void read_input_data(void){
   int n,b;
  
   scanf("%d%d",&bolts,&nuts);
   for(b=0;b      for(n=0;n         scanf("%d",&fits[b][n]);
         }
      }
   }

/* data used to match nuts with bolts */
int nut_used[MAX_NUTS];
int bestmatched;

void init_match(void){
   int n;
  
   bestmatched=0;
   for(n=0;n   }
  
void match_bolt(int boltno, int matched){
   int n;
  
   if(boltno==bolts){
      if(matched>bestmatched) bestmatched=matched;
      return;
      }
     
   /* don't match this bolt */
   match_bolt(boltno+1,matched);
  
   /* match with all unused nuts that fit this bolt */
   for(n=0;n      nut_used[n]=1;
      match_bolt(boltno+1,matched+1);
      nut_used[n]=0;
      }
   }
  
int main(){
   int cases,caseno;
  
   scanf("%d",&cases);
   for(caseno=1;caseno<=cases;caseno++){
      read_input_data();
      init_match();
      match_bolt(0,0);
      printf("Case %d: ",caseno);
      printf("a maximum of %d nuts and bolts ",bestmatched);
      printf("can be fitted together\n");
      }
     
   return 0;
   }

This is the code that Jimmy sent you by email.
A plain-text version can be found here.

Sample Input

2
3 4
0 0 1 0
1 1 0 1
0 0 1 0
5 5
1 0 0 1 1
1 1 0 0 0
1 0 0 0 0
0 1 1 0 0
0 0 0 0 1 

Sample Output

Case 1: a maximum of 2 nuts and bolts can be fitted together
Case 2: a maximum of 5 nuts and bolts can be fitted together

Problem Setter: Joachim Wulff, Special Thanks: Igor Naverniouk
PS. If you are a Pascal programmer and you don't understand C, then you're in trouble: in 2006 it was the last time that Pascal was allowed at the ICPC World Finals and other programming contests will probably follow soon. Better learn C or one of its derivatives!

bipartite graph
#include <stdio.h>
#include<cstring>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define MAXN 500

/* global copy of the input data */
int nuts,bolts;
int fits[MAXN][MAXN],xM[MAXN],yM[MAXN], cases,caseno;
bool trav[MAXN];
void read_input_data(){
int n,b;
scanf("%d%d",&bolts,&nuts);
for(b=0;b<bolts;b++)for(n=0;n<nuts;n++)scanf("%d",&fits[b][n]);
}
bool search(int a){
rep(i,nuts){
if(fits[a][i]&&!trav[i]){
trav[i]=1;
if(yM[i]<0||search(yM[i])){
xM[a]=i,yM[i]=a;
return 1;
}
}
}
return 0;
}
void ans(){
int res=0;
memset(xM,-1,sizeof(xM));
memset(yM,-1,sizeof(yM));
rep(i,bolts){
memset(trav,0,sizeof(trav));
if(xM[i]<0&&search(i))res++;
}
printf("Case %d: ",caseno);
printf("a maximum of %d nuts and bolts can be fitted together\n",res);
}
int main(){
scanf("%d",&cases);
for(caseno=1;caseno<=cases;caseno++){
read_input_data();
ans();
}
return 0;
}

uva 10349 - Antenna Placement


Problem E
Antenna Placement 
Input: standard input
Output: standard output
Time Limit: 1 second
Memory Limit: 32 MB

The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobile phone nets in Sweden. The most striking reason why they got the job, is their discovery of a new, highly noise resistant, antenna. It is called 4DAir, and comes in four types. Each type can only transmit and receive signals in a direction aligned with a (slightly skewed) latitudinal and longitudinal grid, because of the interacting electromagnetic field of the earth. The four types correspond to antennas operating in the directions north, west, south, and east, respectively. Below is an example picture of places of interest, depicted by twelve small rings, and nine 4DAir antennas depicted by ellipses covering them.
 
Obviously, it is desirable to use as few antennas as possible, but still provide coverage for each place of interest. We model the problem as follows: Let A be a rectangular matrix describing the surface of Sweden, where an entry of A either is a point of interest, which must be covered by at least one antenna, or empty space. Antennas can only be positioned at an entry in A. When an antenna is placed at row r and column c, this entry is considered covered, but also one of the neighbouring entries (c+1,r),(c,r+1),(c-1,r), or (c,r-1), is covered depending on the type chosen for this particular antenna. What is the least number of antennas for which there exists a placement in A such that all points of interest are covered?

Input
On the first row of input is a single positive integer n, specifying the number of scenarios that follow. Each scenario begins with a row containing two positive integers h and w, with 1<h<40 i="i" nbsp="nbsp">and 0<w<10 i="i">. Thereafter is a matrix presented, describing the points of interest in Sweden in the form of h lines, each containing w characters from the set [‘*’,’o’]. A ‘*’-character symbolises a point of interest, whereas a ‘o’-character represents open space.

Output

For each scenario, output the minimum number of antennas necessary to cover all ‘*’-entries in the scenario’s matrix, on a row of its own.

Sample Input      
2                      
7 9                    
ooo**oooo
**oo*ooo*
o*oo**o**
ooooooooo
*******oo
o*o*oo*oo
*******oo
10 1
*
*
*
o
*
*
*
*
*
*

Sample Output 
17
5

Swedish National Contest.

bipartite graph, 用flooding建立X集合與Y集合,求最大匹配
#include<stdio.h>
#include<cstring>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
#define MAXM 1600
#define MAXN 400
using namespace std;

int dir[4][2],e,D,R,C;
int v[MAXM],next[MAXM],head[MAXN];
int mate[MAXN][2],num[40][10],xM[MAXN],yM[MAXN],type[MAXN];
char maz[40][11];
bool trav[MAXN];
void addedge(int a,int b){
v[e]=b,next[e]=head[a],head[a]=e,e++;
v[e]=a,next[e]=head[b],head[b]=e,e++;
}
void init(){
dir[0][0]=-1,dir[1][1]=-1,dir[2][0]=1,dir[3][1]=1;
}
bool isValid(int a,int b){return a>=0&&a<R&&b>=0&&b<C;}
bool search(int t){
if(DBG)printf("search: (%d,%d), xM %d\n",mate[t][0],mate[t][1],xM[t]);
int a;
for(a=head[t];a>=0;a=next[a]){
if(DBG)printf(" look: (%d,%d), xM %d\n",mate[v[a]][0],mate[v[a]][1],xM[v[a]]);
if(!trav[v[a]]){
trav[v[a]]=1;
if(yM[v[a]]<0||search(yM[v[a]])){
xM[t]=v[a],yM[v[a]]=t;
return 1;
}
}
}
return 0;
}
void ans(){
int res=0;
memset(xM,-1,sizeof(xM));
memset(yM,-1,sizeof(yM));
rep(i,D){
if(type[i]==1&&xM[i]<0){ //X
if(DBG)printf("search (%d,%d)\n",mate[i][0],mate[i][1]);
memset(trav,0,sizeof(trav));
if(search(i)){
if(DBG)printf("add (%d,%d)-(%d,%d)\n",mate[i][0],mate[i][1],
mate[xM[i]][0],mate[xM[i]][1]);
res++;
}
}
}
printf("%d\n",D-res);
}
void flood(int x,int y,int n){
int a,b;
rep(i,4){
a=x+dir[i][0],b=y+dir[i][1];
if(isValid(a,b)&&maz[a][b]=='*'&&!type[num[a][b]]){
type[num[a][b]]=n==1?2:1;
flood(a,b,type[num[a][b]]);
}
}
}
void build(){
int a,b;
D=0;memset(type,0,sizeof(type));
rep(i,R)rep(j,C){if(maz[i][j]=='*')mate[D][0]=i,mate[D][1]=j,num[i][j]=D++;}
rep(i,R)rep(j,C)
if(maz[i][j]=='*'){
if(!type[num[i][j]])
type[num[i][j]]=1,flood(i,j,1); //build bipartite
}
rep(i,R)rep(j,C)
if(maz[i][j]=='*')
rep(k,4){
a=i+dir[k+2][0],b=j+dir[k+2][1];
if(isValid(a,b)&&maz[a][b]=='*')addedge(num[i][j],num[a][b]);
}
}
int main(){
int a,b,n;
init();
scanf("%d",&n);
rep(i,n){
e=0,memset(head,-1,sizeof(head));
scanf("%d%d",&R,&C);
rep(i,R)scanf("%s",maz[i]);
build();
ans();
}
}