标签:java
朋友圈转发信息 | |
描述: |
在一个社交应用中,两个用户设定朋友关系后,则可以互相收到对方发布或转发的信息。当一个用户发布或转发一条信息时,他的所有朋友都能收到该信息。
现给定一组用户,及用户之间的朋友关系。 问:当某用户发布一条信息之后,为了让每个人都能在最早时间收到这条信息,这条信息最少需要被转发几次?
假设:对所有用户而言: 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(); } }
标签:java
原文地址:http://blog.csdn.net/guorudi/article/details/44683463