Facility Locations: Difference between revisions

From programming_contest
Jump to navigation Jump to search
imported>Kmk21
Created page with "= Introduction = This asks you to select k of m (100) facility locations such that each of n (100) clients has a 0-length path to one of the k facilities. = Solutions= == Gre..."
 
imported>Kmk21
No edit summary
 
Line 42: Line 42:
[[Category:ICPC Problems]]
[[Category:ICPC Problems]]
[[category:greedy]]
[[category:greedy]]
[[category:graph]]
[[Category:Algorithm Medium]]
[[Category:Algorithm Medium]]
[[Category:Implementation Easy]]
[[Category:Implementation Easy]]

Latest revision as of 00:17, 17 February 2015

Introduction

This asks you to select k of m (100) facility locations such that each of n (100) clients has a 0-length path to one of the k facilities.

Solutions

Greedy

Consider the fancy equation c(ij) <= c(i'j) + c(i'j') + c(ij'). This equation implies that if I have 0 distance to some node, and non-zero distance to some other node, then any other node with 0 distance to this node also has non-zero distance to that other node. (hint: put the "non-zero" distance as c(ij), and the equation no longer balances). This means that if some node has multiple facilities which serve it, then those facilities will serve all the same nodes...so we can greedily select whichever one, and know that it doesn't make any difference.

Go though the nodes, and when you find one uncovered by a facility, select that facility and mark all other nodes that facility serves as covered.

Note: this is equivalent to realizing that any facility/node groups have a complete bipartite matching, and thus simply checking that there are k connected components (assigning a facility to each one)

Code

Solution - Java

import java.util.*;
public class d {
	Scanner in=new Scanner(System.in);
	public static void main(String[] args) {
		new d().go();
	}
	private void go() {
		int m=in.nextInt(),n=in.nextInt(),k=in.nextInt();
		int[][] d=new int[m][n];
		for(int i=0;i<m;i++)for(int j=0;j<n;j++)d[i][j]=in.nextInt();
		HashSet<Integer>done=new HashSet<Integer>();
		for(int i=0;i<m;i++)for(int j=0;j<n;j++)if(d[i][j]==0&&!done.contains(j)){//found uncovered node with length 0
			if(k==0){//oops already used our allotment
				System.out.println("no");
				System.exit(0);
			}
			k--;
			for(;j<n;j++)if(d[i][j]==0)done.add(j);//cover any nodes left here
		}
		if(done.size()==n)System.out.println("yes");
		else System.out.println("no");
	}
}