2012年10月19日 星期五

uva 10801 - Lift Hopping


Problem ?
Lift Hopping
Time Limit: 1 second

Ted the bellhop: "I'm coming up and if there isn't
a dead body by the time I get there, I'll make one
myself. You!"
Robert Rodriguez, "Four Rooms."
A skyscraper has no more than 100 floors, numbered from 0 to 99. It has n (1<=n<=5) elevators which travel up and down at (possibly) different speeds. For each i in {1, 2,... n}, elevator number i takes Ti (1<=Ti<=100) seconds to travel between any two adjacent floors (going up or down). Elevators do not necessarily stop at every floor. What's worse, not every floor is necessarily accessible by an elevator.
You are on floor 0 and would like to get to floor k as quickly as possible. Assume that you do not need to wait to board the first elevator you step into and (for simplicity) the operation of switching an elevator on some floor always takes exactly a minute. Of course, both elevators have to stop at that floor. You are forbiden from using the staircase. No one else is in the elevator with you, so you don't have to stop if you don't want to. Calculate the minimum number of seconds required to get from floor 0 to floor k (passing floor k while inside an elevator that does not stop there does not count as "getting to floork").
Input
The input will consist of a number of test cases. Each test case will begin with two numbers, n and k, on a line. The next line will contain the numbers T1T2,... Tn. Finally, the next n lines will contain sorted lists of integers - the first line will list the floors visited by elevator number 1, the next one will list the floors visited by elevator number 2, etc.
Output
For each test case, output one number on a line by itself - the minimum number of seconds required to get to floor k from floor 0. If it is impossible to do, print "IMPOSSIBLE" instead.
Sample InputSample Output
2 30
10 5
0 1 3 5 7 9 11 13 15 20 99
4 13 15 19 20 25 30
2 30
10 1
0 5 10 12 14 20 25 30
2 4 6 8 10 12 14 22 25 28 29
3 50
10 50 100
0 10 30 40
0 20 30
0 20 50
1 1
2
0 2 4 6 8 10
275
285
3920
IMPOSSIBLE
Explanation of examples
In the first example, take elevator 1 to floor 13 (130 seconds), wait 60 seconds to switch to elevator 2 and ride it to floor 30 (85 seconds) for a total of 275 seconds.
In the second example, take elevator 1 to floor 10, switch to elevator 2 and ride it until floor 25. There, switch back to elevator 1 and get off at the 30'th floor. The total time is
10*10 + 60 + 15*1 + 60 + 5*10 = 285 seconds.
In example 3, take elevator 1 to floor 30, then elevator 2 to floor 20 and then elevator 3 to floor 50.
In the last example, the one elevator does not stop at floor 1.


Problemsetter: Igor Naverniouk
Alternate solutions: Stefan Pochmann, Frank Pok Man Chu

shortest path - bfs
#include<stdio.h>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#include<sstream>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define MAXN 5
#define MAXF 100
#define DBG 0
using namespace std;

int N,M,next[MAXN][MAXF],pre[MAXN][MAXF],spd[MAXN];
bool dps[MAXN][MAXF],isc[MAXN][MAXF];
vector<int>eg[MAXF];
struct Node{
Node(int a,int b,int c):ele(a),flr(b),min(c){}
bool operator < (const Node b)const{return min>b.min;}
int ele,flr,min;
};
void ans(){
int a,b,c,na,nb[2];
bool ok=0;
memset(dps,0,sizeof(dps));
priority_queue<Node>q;
rep(i,N)if(isc[i][0])dps[i][0]=1,q.push(Node(i,0,0));
while(q.size()){
a=q.top().ele,b=q.top().flr,c=q.top().min,q.pop();
if(DBG)printf("bfs %d %d %d\n",a,b,c);
if(b==M){ok=1;break;}
dps[a][b]=1;
nb[0]=next[a][b],nb[1]=pre[a][b]; //switch floor
rep(i,2)
if(nb[i]>0&&!dps[a][nb[i]]){
q.push(Node(a,nb[i],c+spd[a]*abs(nb[i]-b))); //original ele
}
rep(i,eg[b].size()){ //switch elevator
na=eg[b][i];
if(na!=a){
if(DBG)printf("switch flr: %d %d\n",na,c+60);
if(!dps[na][b])q.push(Node(na,b,c+60));}
}
}
if(ok)printf("%d\n",c);
else printf("IMPOSSIBLE\n");
}
int main(){
int a,b,c,pa;
char chs[400];
stringstream buf;
while(scanf("%d%d",&N,&M)==2){
if(DBG)printf("N M %d %d\n",N,M);
rep(i,MAXF)eg[i].clear();memset(isc,0,sizeof(isc));
memset(pre,0,sizeof(pre)),memset(next,0,sizeof(next));
rep(i,N)scanf("%d ",&spd[i]);
rep(i,N){
fgets(chs,400,stdin);pa=-1;
if(chs[strlen(chs)-1]=='\n')chs[strlen(chs)-1]='\0';
buf.clear(),buf.str(chs);
while(!buf.eof()){
buf>>a;
if(pa>=0)pre[i][a]=pa,next[i][pa]=a;
eg[a].push_back(i);isc[i][a]=1;
pa=a;
}
}
ans();
}
return 0;
}

uva 11101 - Mall Mania


Problem B: Mall Mania

Waterloo has two giant shopping malls, each enclosing several city blocks. Kim and Pat like to shop and to walk within the malls but they don't like walking between the malls because such walking does not contribute directly to the task at hand: shopping. They would therefore like to know the minimum crossing distance between the malls.Each city block is a unit square delimited by streets and avenues. Streets run east-west and avenues run north-south. Both are identified by consecutive integers between 0 and 2000. (Lower numbered avenues are west of higher numbered avenues and lower numbered streets are south of higher numbered streets.) Streets and avenues are narrow so their thickness may be assumed to be 0.
Each mall is a contiguous set of complete city blocks. By contiguous we mean that any two blocks are connected by some sequence of blocks such that consecutive pairs of blocks in the sequence share a side. The malls do not intersect and do not surround any empty blocks; that is, the blocks not in any mall are themselves contiguous.
Standard input contains several test cases. Each test case contains the description of the two malls. Each mall's description consists of an integer p ≥ 4, the perimeter of the mall, followed by one or more lines containing p pairs (a,s) giving the coordinates of the avenue-street intersections contained in the perimeter, in clockwise order. A line containing 0 follows the last test case.
For each case, output a single integer d -- the minimum walking distance between the malls, assuming that Kim and Pat always walk along streets and avenues.

Sample Input

4
0 0 0 1 1 1 1 0
6
4 3 4 2 3 2
2 2 2 3
3 3
0

Output for Sample Input

2

Gordon V. Cormack

shortest path - BFS
#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 MAXN 2001
#define DBG 0
using namespace std;

int N,M,cases=1,dir[4][2];
bool dps[MAXN][MAXN],m1[MAXN][MAXN],m2[MAXN][MAXN];
vector<pair<int,int> >seq;
struct Node{
Node(int a,int b,int c):x(a),y(b),dis(c){}
int x,y,dis;
};
void init(){
dir[0][0]=-1,dir[1][1]=-1,dir[2][0]=1,dir[3][1]=1;
}
bool valid(int a,int b){return a>=0&&a<2000&&b>=0&&b<2000;}
void ans(){
int x,y,a,b,d;
bool ok=0;
memset(dps,0,sizeof(dps));
queue<Node>q;
rep(i,seq.size())q.push(Node(seq[i].first,seq[i].second,0));
while(q.size()){
a=q.front().x,b=q.front().y,d=q.front().dis,q.pop();
if(DBG)printf("bfs %d %d\n",a,b);
dps[a][b]=1;
rep(i,4){
x=a+dir[i][0],y=b+dir[i][1];
if(valid(x,y)&&!m1[x][y]&&!dps[x][y]){ //don't walk in mall and previous pos
dps[x][y]=1;
if(m2[x][y]){if(DBG)printf("find %d %d\n",x,y);d++,ok=1;break;}
q.push(Node(x,y,d+1));
}
}
if(ok)break;
}
printf("%d\n",d);
}
int main(){
int a,b,c;
bool ll=0;
init();
while(scanf("%d",&N)==1){
memset(m1,0,sizeof(m1));memset(m2,0,sizeof(m2));
seq.clear();
if(N==0)break;
rep(i,N)scanf("%d%d",&a,&b),m1[a][b]=1,seq.push_back(make_pair(a,b));;
scanf("%d",&N);
rep(i,N)scanf("%d%d",&a,&b),m2[a][b]=1;
ans();
}
return 0;
}

uva 10047 - The Monocycle



  Problem A: The Monocycle 

A monocycle is a cycle that runs on one wheel and the one we will be considering is a bit more special. It has a solid wheel colored with five different colors as shown in the figure:

The colored segments make equal angles (72o) at the center. A monocyclist rides this cycle on an $M \times N$ grid of square tiles. The tiles have such size that moving forward from the center of one tile to that of the next one makes the wheel rotate exactly 72o around its own center. The effect is shown in the above figure. When the wheel is at the center of square 1, the mid­point of the periphery of its blue segment is in touch with the ground. But when the wheel moves forward to the center of the next square (square 2) the mid­point of its white segment touches the ground.

Some of the squares of the grid are blocked and hence the cyclist cannot move to them. The cyclist starts from some square and tries to move to a target square in minimum amount of time. From any square either he moves forward to the next square or he remains in the same square but turns 90o left or right. Each of these actions requires exactly 1 second to execute. He always starts his ride facing north and with the mid­point of the green segment of his wheel touching the ground. In the target square, too, the green segment must be touching the ground but he does not care about the direction he will be facing.
Before he starts his ride, please help him find out whether the destination is reachable and if so the minimum amount of time he will require to reach it.

Input 

The input may contain multiple test cases.
The first line of each test case contains two integers M and N ($1 \le M$$N \le 25$) giving the dimensions of the grid. Then follows the description of the grid in M lines of N characters each. The character `#' will indicate a blocked square, all other squares are free. The starting location of the cyclist is marked by `S' and the target is marked by `T'. The input terminates with two zeros for M and N.

Output 

For each test case in the input first print the test case number on a separate line as shown in the sample output. If the target location can be reached by the cyclist print the minimum amount of time (in seconds) required to reach it exactly in the format shown in the sample output, otherwise, print ``destination not reachable".
Print a blank line between two successive test cases.

Sample Input 

1 3
S#T
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
0 0

Sample Output 

Case #1
destination not reachable
 
Case #2
minimum time = 49 sec



Miguel Revilla
2000-12-26

shortest path, BFS
#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 MAXN 25
#define DBG 0
using namespace std;

int N,M,cases=1,dir[4][2];
char maz[MAXN][MAXN+1];
bool dps[MAXN][MAXN][4][5];
struct Node{
Node(int a,int b,int c,int d,int e):x(a),y(b),face(c),wheel(d),dis(e){}
int face,x,y,dis,wheel;
};
void init(){
dir[0][0]=-1,dir[1][1]=-1,dir[2][0]=1,dir[3][1]=1;
}
bool valid(int a,int b){return a>=0&&a<N&&b>=0&&b<M;}
void ans(){
int a,b,c,d,x,y,e,w,si,sj,ei,ej,nw,nd[2];
bool ok=0;
memset(dps,0,sizeof(dps));
rep(i,N)rep(j,M){
if(maz[i][j]=='S')si=i,sj=j;
if(maz[i][j]=='T')ei=i,ej=j;}
queue<Node>q;
q.push(Node(si,sj,0,0,0)); //face north, wheel zero
while(q.size()){
a=q.front().x,b=q.front().y,c=q.front().face,w=q.front().wheel,
d=q.front().dis,q.pop();
if(DBG)printf("bfs a b face wheel dis %d %d %d %d %d\n",a,b,c,w,d);
dps[a][b][c][w]=1;
if(a==ei&&b==ej&&w==0){ok=1;break;}
nd[0]=(c+1)%4,nd[1]=(c-1)<0?3:c-1;
rep(i,2) //direction
if(!dps[a][b][nd[i]][w]){
dps[a][b][nd[i]][w]=1;
q.push(Node(a,b,nd[i],w,d+1));}
x=a+dir[c][0],y=b+dir[c][1],nw=(w+1)%5; //walk
if(valid(x,y)&&maz[x][y]!='#'&&!dps[x][y][c][nw]){
dps[x][y][c][nw]=1;
q.push(Node(x,y,c,nw,d+1));}
}
printf("Case #%d\n",cases++);
if(ok)printf("minimum time = %d sec\n",d);
else printf("destination not reachable\n");

}
int main(){
int a,b,c;
bool ll=0;
init();
while(scanf("%d%d",&N,&M)==2){
if(DBG)printf("N M %d %d\n",N,M);
if(N+M==0)break;
rep(i,N)scanf("%s",maz[i]);
if(ll)printf("\n");ll=1;ans();
}
return 0;
}

uva 321 - The New Villa



 The New Villa 

Mr. Black recently bought a villa in the countryside. Only one thing bothers him: although there are light switches in most rooms, the lights they control are often in other rooms than the switches themselves. While his estate agent saw this as a feature, Mr. Black has come to believe that the electricians were a bit absent-minded (to put it mildly) when they connected the switches to the outlets.
One night, Mr. Black came home late. While standing in the hallway, he noted that the lights in all other rooms were switched off. Unfortunately, Mr. Black was afraid of the dark, so he never dared to enter a room that had its lights out and would never switch off the lights of the room he was in.
After some thought, Mr. Black was able to use the incorrectly wired light switches to his advantage. He managed to get to his bedroom and to switch off all lights except for the one in the bedroom.

You are to write a program that, given a description of a villa, determines how to get from the hallway to the bedroom if only the hallway light is initially switched on. You may never enter a dark room, and after the last move, all lights except for the one in the bedroom must be switched off. If there are several paths to the bedroom, you have to find the one which uses the smallest number of steps, where ``move from one room to another'', ``switch on a light'' and ``switch off a light'' each count as one step.

Input

The input file contains several villa descriptions. Each villa starts with a line containing three integers rd, and sr is the number of rooms in the villa, which will be at most 10. d is the number of doors/connections between the rooms and s is the number of light switches in the villa. The rooms are numbered from 1 to r; room number 1 is the hallway, room number r is the bedroom.
This line is followed by d lines containing two integers i and j each, specifying that room i is connected to room j by a door. Then follow s lines containing two integers k and l each, indicating that there is a light switch in room k that controls the light in room l.

A blank line separates the villa description from the next one. The input file ends with a villa having r = d = s = 0, which should not be processed.

Output

For each villa, first output the number of the test case (`Villa #1'`Villa #2', etc.) in a line of its own.

If there is a solution to Mr. Black's problem, output the shortest possible sequence of steps that leads him to his bedroom and only leaves the bedroom light switched on. (Output only one shortest sequence if you find more than one.) Adhere to the output format shown in the sample below.

If there is no solution, output a line containing the statement `The problem cannot be solved.'

Output a blank line after each test case.

Sample Input


3 3 4
1 2
1 3
3 2
1 2
1 3
2 1
3 2

2 1 2
2 1
1 1
1 2

0 0 0

Sample Output


Villa #1
The problem can be solved in 6 steps:
- Switch on light in room 2.
- Switch on light in room 3.
- Move to room 2.
- Switch off light in room 1.
- Move to room 3.
- Switch off light in room 2.

Villa #2
The problem cannot be solved.

shortest path + bitmask
#include<stdio.h>
#include<cstring>
#include<queue>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define MAXN 10
#define DBG 0
using namespace std;

int N,M,cases=1;
int pre[MAXN][1024][2],child[MAXN][1024][2];
bool on[MAXN],isc[MAXN][MAXN],dps[MAXN][1024];
vector<int>eg[MAXN],ctl[MAXN],seq[MAXN];
struct Node{
Node(int a,int b,int c):status(a),v(b),steps(c){}
int status,v,steps;
};
void setSP(int &s,int pos,int v){
if(v)s|=1<<(N-1-pos); //set to 1
else s&=~(1<<(N-1-pos)); //set to 0
}
bool getSP(int s,int pos){
return s&1<<(N-1-pos);
}
void init(){
memset(isc,0,sizeof(isc));
rep(i,MAXN)seq[i].clear();
rep(i,N)rep(j,ctl[i].size())isc[i][ctl[i][j]]=1;
}
int getLight(int a,int b){
int c=a^b,d=0,e=0;
while(c>0){if(c%2)return N-1-e;e++,c/=2;}
}
void print(int s,int steps){
int c=N-1,pc=-1,c2,s2,d=steps,cnt=0,l;
bool used[MAXN],on[MAXN];
memset(on,0,sizeof(on));on[0]=1;
while(d){
if(DBG)printf("%d %d\n",c,s);
c2=pre[c][s][0],s2=pre[c][s][1];
child[c2][s2][0]=c,child[c2][s2][1]=s;
c=c2,s=s2,d--;
}
c=0,s=1<<N-1,d=steps-1;
printf("The problem can be solved in %d steps:\n",steps-1);
while(d){
if(DBG)printf("%d %d\n",c,s);
if(d<steps-1&&pc!=c)printf("- Move to room %d.\n",c+1);
c2=child[c][s][0],s2=child[c][s][1];
l=getLight(s,s2);
if(c==c2) //switch
if(!on[l])printf("- Switch on light in room %d.\n",l+1),on[l]=1;
else printf("- Switch off light in room %d.\n",l+1),on[l]=0;
pc=c,c=c2,s=s2,d--;
}
}
void ans(){
int a,b,c,d,e,t,s,dis=0;
bool ok=0;
queue<Node>q;
memset(dps,0,sizeof(dps));
t=1<<N-1; //turn on 1
q.push(Node(t,0,1));
while(q.size()){
b=q.front().v,t=q.front().status,dis=q.front().steps,q.pop();
if(DBG)printf("bfs %d %d %d\n",b,t,dis);
if(b==N-1&&t==1){if(DBG)printf("ok\n");ok=1;break;}
dps[b][t]=1;
rep(i,N){
s=t;
if(isc[b][i]){ //turn on/off
a=b;
setSP(s,i,1);
if((getSP(s,a)&&getSP(s,b))&&!dps[a][s]){ //two room must be turned on
dps[a][s]=1,pre[a][s][0]=b,pre[a][s][1]=t;
q.push(Node(s,a,dis+1));}
setSP(s,i,0);
if((getSP(s,a)&&getSP(s,b))&&!dps[a][s]){ //two room must be turned on
dps[a][s]=1,pre[a][s][0]=b,pre[a][s][1]=t;
q.push(Node(s,a,dis+1));}
}
}
s=t;
rep(j,eg[b].size()){ //change room
a=eg[b][j];
if((getSP(s,a)&&getSP(s,b))&&!dps[a][s]){
dps[a][s]=1,pre[a][s][0]=b,pre[a][s][1]=t;
q.push(Node(s,a,dis+1));}
}
}
printf("Villa #%d\n",cases++);
if(N==1)printf("The problem can be solved in 0 steps:\n");
else if(ok)print(t,dis);
else printf("The problem cannot be solved.\n");
}
int main(){
int a,b,c;
while(scanf("%d%d%d",&N,&M,&c)==3){
if(N+M+c==0)break;
rep(i,MAXN)eg[i].clear(),ctl[i].clear();
rep(i,N)eg[i].push_back(i); //self room
rep(i,M)scanf("%d%d",&a,&b),a--,b--,eg[a].push_back(b),eg[b].push_back(a);
rep(i,c)scanf("%d%d",&a,&b),a--,b--,ctl[a].push_back(b);

init();
ans();
printf("\n");
}
return 0;
}

2012年10月17日 星期三

uva 10600 - ACM CONTEST AND BLACKOUT



In order to prepare the “The First National ACM School Contest”(in 20??) the major of the city decided to provide all the schools with a reliable source of power. (The major is really afraid of blackoutsJ). So, in order to do that, power station “Future” and one school (doesn’t matter which one) must be connected; in addition, some schools must be connected as well.

You may assume that a school has a reliable source of power if it’s connected directly to “Future”, or to any other school that has a reliable source of power. You are given the cost of connection between some schools. The major has decided to pick out two the cheapest connection plans – the cost of the connection is equal to the sum of the connections between the schools. Your task is to help the major – find the cost of the two cheapest connection plans.

Input

The Input starts with the number of test cases, T (1£T£15) on a line. Then T test cases follow. The first line of every test case contains two numbers, which are separated by a space, N (3£N£100) the number of schools in the city, and M the number of possible connections among them. Next M lines contain three numbers Ai, Bi, Ci , where Ci  is the cost of the connection (1£Ci£300) between schools Ai  and Bi. The schools are numbered with integers in the range 1 to N.

Output

For every test case print only one line of output. This line should contain two numbers separated by a single space - the cost of two the cheapest connection plans. Let S1 be the cheapest cost and S2 the next cheapest cost. It’s important, that S1=S2 if and only if there are two cheapest plans, otherwise S1£S2. You can assume that it is always possible to find the costs S1 and S2..

Sample Input
Sample Output
2
5 8
1 3 75
3 4 51
2 4 19
3 2 95
2 5 42
5 4 31
1 2 9
3 5 66
9 14
1 2 4
1 8 8
2 8 11
3 2 8
8 9 7
8 7 1
7 9 6
9 3 2
3 4 7
3 6 4
7 6 2
4 6 14
4 5 9
5 6 10
110 121
37 37

Problem source: Ukrainian National Olympiad in Informatics 2001
Problem author: Shamil Yagiyayev
Problem submitter: Dmytro Chernysh
Problem solution: Shamil Yagiyayev, Dmytro Chernysh, K M Hasan


minimum spanning tree, second minimum spanning tree -find alternative path by replacing any existing edge with sub-optimal one.
#include<stdio.h>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#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 5000
#define INF int(1e9)
using namespace std;

int N,M,e;
int v1[MAXM],v2[MAXM],w[MAXM],p[MAXN],inv[MAXM];
struct Node{
Node(int ed,int a,int b,int c):e(ed),v1(a),v2(b),dis(c){}
bool operator <(const Node b)const {return dis>b.dis;}
int e,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,int p[]){
if(p[v]==v)return v;
return p[v]=find(p[v],p);
}
void unit(int from,int to,int p[]){
p[find(from,p)]=p[find(to,p)];
}
void ans(){
int a,b,c,d=0,ce,s1=0,s2=0,m=INF;
priority_queue<Node>q,q2;
vector<int>ed;
rep(i,e)q.push(Node(i,v1[i],v2[i],w[i]));
q2=q;
rep(i,N)p[i]=i;
while(d<N-1){
ce=q.top().e,a=q.top().v1,b=q.top().v2,c=q.top().dis,q.pop();
if(DBG)printf("a b %d %d %d\n",a,b,c);
if(find(a,p)!=find(b,p))unit(a,b,p),ed.push_back(ce),s1+=c,d++;
}
rep(i,ed.size()){
inv[ed[i]]=1;
q=q2,d=0,s2=0;
rep(j,N)p[j]=j;
while(q.size()&&d<N-1){
ce=q.top().e,a=q.top().v1,b=q.top().v2,c=q.top().dis,q.pop();
if(!inv[ce]){
//if(DBG)printf("a b %d %d %d\n",a,b,c);
if(find(a,p)!=find(b,p))unit(a,b,p),s2+=c,d++;
}
}
if(d==N-1&&s2<m)m=s2;
inv[ed[i]]=0;
}
printf("%d %d\n",s1,m);
}
int main(){
int a,b,c,n;
bool ll=0;
scanf("%d",&n);
rep(i,n){
e=0;
scanf("%d%d",&N,&M);
rep(i,M)scanf("%d%d%d",&a,&b,&c),a--,b--,addedge(a,b,c);
ans();
}
return 0;
}

uva 10369 - Arctic Network


Problem C: Arctic Network

The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel.Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts.
Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.
The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000). For each case, output should consist of a single line giving the minimum D required to connect the network. Output should be specified to 2 decimal points.

Sample Input

1
2 4
0 100
0 300
0 600
150 750

Sample Output

212.13

#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 500
using namespace std;

int N,S;
int p[MAXN],cor[MAXN][2];
struct Node{
Node(int a,int b,double c):v1(a),v2(b),dis(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 ans(){
double m=0,c;
int a,b,d=0;
priority_queue<Node>q;
rep(i,N)REP(j,i+1,N){c=getD(i,j),q.push(Node(i,j,c));if(DBG)printf("a b %d %d %f\n",i,j,c);}
rep(i,N)p[i]=i;
while(d<N-S){
a=q.top().v1,b=q.top().v2,c=q.top().dis,q.pop();
if(DBG)printf("a b %d %d %f\n",a,b,c);
if(find(a)!=find(b))unit(a,b),m=max(m,c),d++;
}
printf("%.2f\n",m);
}
int main(){
int n;
bool ll=0;
scanf("%d",&n);
rep(i,n){
scanf("%d%d",&S,&N);
rep(i,N)scanf("%d%d",&cor[i][0],&cor[i][1]);
ans();
}
return 0;
}

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­GA­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: c1c2 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 CS 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 Ak1 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 67 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 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();
}
}

2012年10月16日 星期二

uva 10596 - Morning Walk



Problem H
Morning Walk
Time Limit
3 Seconds

Kamal is a Motashota guy. He has got a new job in Chittagong. So, he has moved to Chittagong from Dinajpur. He was getting fatter in Dinajpur as he had no work in his hand there. So, moving to Chittagong has turned to be a blessing for him. Every morning he takes a walk through the hilly roads of charming city Chittagong. He is enjoying this city very much. There are so many roads in Chittagong and every morning he takes different paths for his walking. But while choosing a path he makes sure he does not visit a road twice not even in his way back home. An intersection point of a road is not considered as the part of the road. In a sunny morning, he was thinking about how it would be if he could visit all the roads of the city in a single walk. Your task is to help Kamal in determining whether it is possible for him or not.

Input
Input will consist of several test cases. Each test case will start with a line containing two numbers. The first number indicates the number of road intersections and is denoted by N (2 ≤ N ≤ 200). The road intersections are assumed to be numbered from 0 to N-1. The second number R denotes the number of roads (0 ≤ R ≤ 10000). Then there will be R lines each containing two numbers c1 and c2 indicating the intersections connecting a road.

Output
Print a single line containing the text “Possible” without quotes if it is possible for Kamal to visit all the roads exactly once in a single walk otherwise print “Not Possible”.

Sample Input
Output for Sample Input
2
0 1
1 0
2 1
0 1
Possible
Not Possible

Problemsetter: Muhammad Abul Hasan
International Islamic University Chittagong

euler graph check, notice weird requirement: M=0 -> not possible
#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
using namespace std;

int N,M,D;
int cnt[MAXN],adx[MAXN][MAXN];
bool trav[MAXN];
void DFS(int a){
if(DBG)printf("dfs %d\n",a);
trav[a]=1,D++;
rep(i,cnt[a]){
if(!trav[adx[a][i]])DFS(adx[a][i]);
}
}
void ans(){
int i,c=0;
for(i=0;i<N;i++){
if(cnt[i]%2){printf("Not Possible\n");return;}
if(cnt[i])c++;
}
memset(trav,0,sizeof(trav)),D=0;
rep(i,N)if(cnt[i]){DFS(i);break;}
if(D<c)printf("Not Possible\n");
else printf("Possible\n");
}
int main(){
int a,b;
while(scanf("%d%d",&N,&M)==2){
memset(cnt,0,sizeof(cnt));
rep(i,M)scanf("%d%d",&a,&b),adx[a][cnt[a]++]=b,adx[b][cnt[b]++]=a;
if(!M)printf("Not Possible\n"); //weird judge
else ans();
}
}