华为2015年实习生招聘模拟1 4439 朋友圈转发信息 [ 最短路 + 二分图匹配 + 状压暴力 ]

 

朋友圈转发信息
描述:

在一个社交应用中,两个用户设定朋友关系后,则可以互相收到对方发布或转发的信息。当一个用户发布或转发一条信息时,他的所有朋友都能收到该信息。

 

现给定一组用户,及用户之间的朋友关系。

问:当某用户发布一条信息之后,为了让每个人都能在最早时间收到这条信息,这条信息最少需要被转发几次?

 

假设:对所有用户而言:

1)朋友发出信息到自己收到该信息的时延为T(T>0);

2)如需转发,从收到信息到转发出信息的时延为0。

 

用例保证:在给定的朋友圈关系中,任何人发布的信息总是能通过N(N>=0)次转发让其他所有用户收到。

 

例如:

下图表示某个朋友圈关系(节点间连线表示朋友关系)中,用户1在时刻0发布信息之后,两种不同的转发策略。

黄色节点表示转发用户,蓝色数字为用户收到信息的时间

 

 

 

 

运行时间限制: 无限制
内存限制: 无限制
输入:

Sender

[消息创建者编号]

Relationship

[朋友关系列表,1,2 表示1和2是朋友关系]

End

 

如下:

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

输出:

当某用户发布一条信息之后,为了让每个人都能在最早时间收到这条信息,这条信息最少需要被转发的次数

 

样例输入:
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中需要的最小点数。

对于这个匹配问题,窝是没想出什么太好的方法,网上传的一个贪心的做法是错误的。

由于不知道数据范围,开始没敢暴力,不过,经kss测试,数据范围很小,可以暴力,那么把上层集合状压暴力一下就好。

一个剪枝:如果下层某个用户只有一个上层的父亲节点,那么该父亲节点必选。

 

1643144 陈志阳 Q5J7H45T 朋友圈转发信息 正确 C++ 3H 24M 40S 160 2015-03-26 21:01:07

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <stack>
  4 #include <vector>
  5 #include <queue>
  6 #include <algorithm>
  7 
  8 #define ll long long
  9 int const N = 105;
 10 int const M = 205;
 11 int const inf = 1000000000;
 12 ll const mod = 1000000007;
 13 
 14 using namespace std;
 15 
 16 int root;
 17 vector<int> ibian[N];
 18 vector<int> dbian[N];
 19 vector<int> ubian[N];
 20 int ru[N];
 21 int chu[N];
 22 char s[N];
 23 int ans;
 24 vector<int> b[N];
 25 int d[N];
 26 typedef pair<int,int> P;
 27 int vis[N];
 28 int totcen;
 29 
 30 void ini()
 31 {
 32     int i;
 33     ans=0;
 34     memset(ru,0,sizeof(ru));
 35     memset(chu,0,sizeof(chu));
 36     memset(vis,0,sizeof(vis));
 37     for(i=0;i<=100;i++){
 38         ibian[i].clear();
 39         ubian[i].clear();
 40         dbian[i].clear();
 41         b[i].clear();
 42         d[i]=inf;
 43     }
 44     totcen=0;
 45 }
 46 
 47 void dijkstr()
 48 {
 49     priority_queue<P,vector<P>,greater<P> > que;
 50     d[root]=0;
 51     que.push(P(0,root));
 52     vector<int>::iterator it;
 53     while(que.size()>=1)
 54     {
 55         P p=que.top();que.pop();
 56         int v=p.second;
 57         if(d[v]<p.first) continue;
 58         for(it=ibian[v].begin();it!=ibian[v].end();it++){
 59             int index=*it;
 60             if(d[index]>d[v]+1){
 61                 d[index]=d[v]+1;
 62                 que.push(P(d[index],index));
 63             }
 64         }
 65     }
 66 }
 67 
 68 void ini2()
 69 {
 70     vector<int>::iterator it1;
 71     vector<int>::iterator it2;
 72     for(int i=0;i<=100;i++){
 73         if(d[i]==inf) continue;
 74         totcen=max(totcen,d[i]);
 75         b[ d[i] ].push_back(i);
 76     }
 77     for(int i=0;i<=totcen;i++){
 78         for(it1=b[i].begin();it1!=b[i].end();it1++){
 79             int u=*it1;
 80             for(it2=ibian[u].begin();it2!=ibian[u].end();it2++){
 81                 int v=*it2;
 82                 //printf(" u=%d v=%d du=%d dv=%d\n",u,v,d[u],d[v]);
 83                 if( d[v]!=d[u]+1 ) continue;
 84                 dbian[u].push_back(v);
 85                 ubian[v].push_back(u);
 86                 chu[u]++;
 87                 ru[v]++;
 88             }
 89         }
 90     }
 91 
 92 /*
 93     for(int i=0;i<=100;i++){
 94         if(b[i].size()==0) continue;
 95         printf(" i=%d\n",i);
 96         for(it1=b[i].begin();it1!=b[i].end();it1++){
 97             int y=*it1;
 98             printf("  %d ru=%d chu=%d\n",y,ru[y],chu[y]);
 99         }
100         printf("\n");
101     }*/
102 }
103 
104 void cal(int up,int down)
105 {
106     memset(vis,0,sizeof(vis));
107     vector<int>::iterator it1;
108     vector<int>::iterator it2;
109     int u,v,vv;
110     int te=inf;
111     int cntu,cntd;
112     cntu=cntd=0;
113     //int tot;
114     int now;
115     int uu[N];
116 //    int dd[N];
117     //tot=b[down].size();
118     for(it2=b[down].begin();it2!=b[down].end();it2++)
119     {
120         v=*it2;
121         //printf("  v=%d\n",v);
122         if(vis[v]==1) continue;
123         if(ru[v]==1){
124             vis[v]=1;
125             u=*ubian[v].begin();
126             //printf("  u=%d\n",u);
127             vis[u]=1;
128             ans++;
129             for(it1=dbian[u].begin();it1!=dbian[u].end();it1++){
130                 vv=*it1;
131                 vis[vv]=1;
132             }
133         }
134     }
135 
136     for(it1=b[up].begin();it1!=b[up].end();it1++){
137         u=*it1;
138         if(vis[u]==1) continue;
139         uu[cntu]=u;
140         cntu++;
141     }
142 
143     for(it2=b[down].begin();it2!=b[down].end();it2++){
144         v=*it2;
145         if(vis[v]==1) continue;
146   //      dd[cntd]=v;
147         cntd++;
148     }
149     if(cntd==0) return;
150     int o,j;
151     int vis2[N];
152     int cou;
153     for(o=0;o<(1<<cntu);o++)
154     {
155         //printf(" o=%d\n",o);
156         memset(vis2,0,sizeof(vis2));
157         now=0;
158         cou=0;
159         for(j=0;j<cntu;j++){
160             if( (1<<j) & o ){
161                 u=uu[j];
162                 cou++;
163                 for(it1=dbian[u].begin();it1!=dbian[u].end();it1++){
164                     v=*it1;
165                     if(vis[v]==1) continue;
166                     if(vis2[v]==0){
167                         now++;vis2[v]=1;
168                     }
169                 }
170             }
171         }
172         if(now==cntd){
173             te=min(te,cou);
174         }
175     }
176     ans+=te;
177 }
178 
179 void fun()
180 {
181     int i;
182     for(i=1;i<totcen;i++){
183         cal(i,i+1);
184     }
185 }
186 
187 void solve()
188 {
189     //printf(" aftdi\n");
190     dijkstr();
191     //printf(" inidi\n");
192     ini2();
193     //printf(" fundi\n");
194     fun();
195 }
196 
197 void out()
198 {
199     printf("%d\n",ans);
200 }
201 
202 int main()
203 {
204     int u,v;
205     //freopen("data.in","r",stdin);
206     //scanf("%d",&T);
207    // for(cnt=1;cnt<=T;cnt++)
208     //while(T--)
209     ini();
210     scanf("%s",s);
211     scanf("%d",&root);
212     scanf("%s",s);
213     while(scanf("%s",s)!=EOF)
214     {
215         if(s[0]=='E') break;
216         sscanf(s,"%d,%d",&u,&v);
217         ibian[u].push_back(v);
218         ibian[v].push_back(u);
219     }
220     solve();
221     out();
222 }

 

posted on 2015-03-26 21:03  njczy2010  阅读(1026)  评论(0编辑  收藏  举报