朋友圈轉發信息 | |
描述: |
在一個社交應用中,兩個用戶設定朋友關係後,則可以互相收到對方發佈或轉發的信息。當一個用戶發佈或轉發一條信息時,他的所有朋友都能收到該信息。
現給定一組用戶,及用戶之間的朋友關係。 問:當某用戶發佈一條信息之後,爲了讓每個人都能在最早時間收到這條信息,這條信息最少需要被轉發幾次?
假設:對所有用戶而言: 1)朋友發出信息到自己收到該信息的時延爲T(T>0); 2)如需轉發,從收到信息到轉發出信息的時延爲0。
用例保證:在給定的朋友圈關係中,任何人發佈的信息總是能通過N(N>=0)次轉發讓其他所有用戶收到。
例如: 下圖表示某個朋友圈關係(節點間連線表示朋友關係)中,用戶1在時刻0發佈信息之後,兩種不同的轉發策略。 黃色節點表示轉發用戶,藍色數字爲用戶收到信息的時間。
|
運行時間限制: | 無限制 |
內存限制: | 無限制 |
輸入: |
Sender [消息創建者編號] Relationship [朋友關係列表,1,2 表示1和2是朋友關係] End
如下: Sender |
輸出: |
當某用戶發佈一條信息之後,爲了讓每個人都能在最早時間收到這條信息,這條信息最少需要被轉發的次數
|
樣例輸入: |
Sender 1 Relationship 1,2 1,3 1,4 2,5 2,6 3,6 4,6 4,7 5,6 5,8 5,9 6,7 6,8 6,9 7,9 10,7 End |
樣例輸出: |
4 |
答案提示: |
|
可以發現,每個用戶接受到信息的時間,是他到起點(消息創建者編號)消息創建着的最短路,故先用最短路預處理。
然後可以發現,收到消息時間爲 T 的用戶是否選擇發佈消息,只會影響到 2T的用戶,(因爲,時間T的用戶的兒子一定是時間爲2T的用戶,因爲每個人都要最早收到消息),而影響不到3T、4T......的用戶。 類似的,2T用戶的決策影響3T用戶。
那麼,問題就簡化成選最少的上層用戶,讓下層每個用戶都收到最早消息,也就是一個二分圖問題。
從u到v,要求能到達v的每一點,u中需要的最小點數
(以上分析摘自我的牛逼師弟http://www.cnblogs.com/njczy2010/p/4370062.html)
然後利用二分答案求解即可
package 朋友圈轉發消息;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
class Node {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + val;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (val != other.val)
return false;
return true;
}
int val;
Node(int val) {
this.val = val;
}
List<Node> next = new ArrayList<>();
}
public class Main {
static Map<Integer, Node> map = new HashMap<>();
static Set<Node> used = new HashSet<>();
static int res = 0;
public static void bfs(int sender){
Queue<Node> que = new LinkedList<>();
Queue<Node> next = new LinkedList<>();
Node seed = map.get(sender);
que.add(seed);
used.add(seed);
while (!que.isEmpty()) {
List<Node> father = new ArrayList<>();
List<Node> son = new ArrayList<>();
Map<Integer,Node> mapSon = new HashMap<>();
List<Node> listUse = new ArrayList<>();
while (!que.isEmpty()) {
Node n = que.poll();
Node fa = new Node(n.val);
father.add(fa);
List<Node> list = n.next;
for (Node node : list) {
if (used.contains(node))
continue;
listUse.add(node);
Node so;
if(mapSon.containsKey(node.val)){
so= mapSon.get(node.val);
}else{
next.add(node);
so = new Node(node.val);
son.add(so);
mapSon.put(node.val, so);
}
fa.next.add(so);
so.next.add(fa);
}
}
for(Node node:listUse){
used.add(node);
}
// /////
bGraph(father, son);
Queue<Node> lin = que;
que = next;
next = lin;
}
}
private static void bGraph(List<Node> father, List<Node> son) {
if(father.size()==1||son.size()==1) {
res +=1;
return;
}
if(son.size()==0) return;
int left =1,right = father.size();
int mid = (left+right)/2;
while(mid<right){
can = false;
sonUsed.clear();
bGraph(father, son, 0, 0, mid);
if (can) {
right = mid;
} else {
left = mid+1;
}
}
res +=mid;
return;
}
static Set<Node> sonUsed = new LinkedHashSet<>();
static boolean can = false;
private static void bGraph(List<Node> father,List<Node> son,int x,int start,int searchTimes){
if(can) return;
if(x==searchTimes){
if(sonUsed.size()==son.size()){
can=true;
}
return;
}
for(int i=start;i<father.size();i++){
Node n = father.get(i);
List<Node> sonAdd = new ArrayList<>();
for(int j=0;j<n.next.size();j++){
Node node = n.next.get(j);
if(!sonUsed.contains(node)){
sonUsed.add(n.next.get(j));
sonAdd.add(node);
}
}
bGraph(father,son,x+1,i+1,searchTimes);
for(int j=0;j<sonAdd.size();j++){
sonUsed.remove(sonAdd.get(j));
}
}
}
public static void main(String args[]) {
/* Scanner sc=null;
try {
sc = new Scanner(new FileInputStream("D://desktop//test.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
Scanner sc = new Scanner(System.in);
String dummy = sc.next();
int sender = sc.nextInt();
String dummy2 = sc.next();
String friend = sc.next();
while (!friend.endsWith("End")) {
String[] str = friend.split(",");
int a = Integer.parseInt(str[0]);
int b = Integer.parseInt(str[1]);
if (a == b) {
friend = sc.next();
continue;
}
Node na;
Node nb;
if (map.containsKey(a)) {
na = map.get(a);
} else {
na = new Node(a);
map.put(a, na);
}
if (map.containsKey(b)) {
nb = map.get(b);
} else {
nb = new Node(b);
map.put(b, nb);
}
na.next.add(nb);
nb.next.add(na);
friend = sc.next();
}
bfs(sender);
System.out.println(res-1);
sc.close();
}
}