朋友圈转发信息

在一个社交应用中,两个用户设定朋友关系后,则可以互相收到对方发布或转发的信息。当一个用户发布或转发一条信息时,他的所有朋友都能收到该信息。
 
现给定一组用户,及用户之间的朋友关系。
问:当某用户发布一条信息之后,为了让每个人都能在最早时间收到这条信息,这条信息最少需要被转发几次?
 
假设:对所有用户而言:
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


10个用例 t_10没过,得分270/300 

方法:暴力求解。

分析:有可能是因为定义静态数组太小导致容量不够,毕竟这个不是ACM,最大容量没有告诉,最好还是动态申请。但这种可能不大。

另求大神指点bug


#include<iostream>
#include<sstream>
#include <cmath>
#include <algorithm>
#include <set>
#include <queue>
#include<vector>
#include <vector>
using namespace std;

#define maxn 200


//输入

class arrGraph
{
public:
	arrGraph()
	{
		cnt.clear();
		sender = 0;
		minNum = 60;
		nodeOfLayer.resize(maxn);
		for( int i = 0 ;i< maxn;i++)
		{
			for(int j = 0; j<maxn ; j++)
			{
				relation[i][j] = 0;
			}
		}
	}
	int insert(int i ,int  j)
	{
		relation[i][j] = 1;
		relation[j][i] = 1;
		return 1;
	}
	void getInput()
	{
		while( getline(cin,input))
		{
			if( input == "Sender")
			{
				cin>>sender;	
				cnt.insert(sender);
			}
			if( input == "Relationship")
			{
				while( cin>>input && input != "End")
				{
					int i = 0;
					int j = 0;
					sscanf(input.c_str(),"%d,%d",&i,&j);
					cnt.insert(i);
					cnt.insert(j);
					insert(i,j);
				}
			}
		}
	}

	void outputG()
	{
		for( int i = 1 ; i<= cnt.size() ;i++)
		{
			cout<<i<<':';
			for(int j = 0; j< cnt.size(); j++)
			{
				if( relation[i][j] == 1)
				{
					printf("(%d,%d)",i,j);
				}
			}
			cout<<endl;
		}
	}
	int getLayer()
	{
		queue<int> q1;
		queue<int >q2;
		int layer = 0;
		q1.push(sender);
		memset(visited,false,sizeof(visited));
		while(!q1.empty() || !q2.empty() )
		{
			while (!q1.empty())
			{
				int t = q1.front();
				visited[t] = true;
				q1.pop();
				for(int j = 1; j<= cnt.size() ; j++)
				{
					if(relation[t][j]==1 && visited[j] == false )
					{
						q2.push(j);
						visited[j] = true;
					}
				}
			}//end while

			while( !q2.empty())
			{
				q1.push(q2.front());
				nodeOfLayer[layer+1].push_back(q2.front());	
				q2.pop();
			}	
			layer++;
		}
		return layer - 1 ;
	}


	void getMinNode( queue<int> q1,vector<int> q2, int curtotalNode, int curLayer,int maxLayer )
	{
		if( cnt.size() == 1 )
		{
			minNum = 0;
			return;
		}
		//初始条件
		if( curLayer == 0)
		{
			memset(visited,false,sizeof(visited));
			q1.push(sender);
			visited[sender] = true;
			curtotalNode = 0;
			
		}

		//终止条件
		if( curLayer == maxLayer)
		{		
			for( int i = 1 ; i< cnt.size() + 1;i++)
			{
				if( visited[i] == false)
					return;
			}
			//如果节点全部访问,更新答案
			if( curtotalNode-1 < minNum)
			{
				minNum = curtotalNode-1;
				return;
			}
		}

		//子问题求解问题分解
		//构造q2
		int cur = q1.size();
		q2.clear();
		while (!q1.empty())
		{
			int t = q1.front();
			visited[t] = true;
			q1.pop();
			int len = cnt.size();
			for(int j = 1; j<=len ; j++)
			{
				if(relation[t][j]==1 && visited[j] == false )
				{
					q2.push_back(j);
					visited[j] = true;
				}
			}
		}//while结束

		//判断是否满足条件
		for( int i = 0; i< nodeOfLayer[curLayer+1].size() ;i++)
		{
			//图中节点是否最早访问
			if( visited[ nodeOfLayer[curLayer+1][i] ] == false)
				return;
		}

		//递归
		int times =  floor(pow(2.0 , (int)q2.size()) - 0.5 ) ;
		for( int i = 1; i <=times;i++)
		{
			//if( curLayer == 0)
			//	cout<<endl;
			//if( curLayer == 1)
			//	cout<<endl;
			//if( curLayer == 2)
			//	cout<<endl;
			int k = i;
			while(!q1.empty()) q1.pop();
			for( int j = 0; j< q2.size();j++)
			{
				if( k & 1 == 1)
				{
					q1.push(q2[j]);
				}
					k = k>>1;	
			}
			//保存现场
			bool visitedc[ maxn ] ;
			memcpy(visitedc,visited,sizeof(visited));
			getMinNode( q1, q2, curtotalNode +cur ,curLayer+1,maxLayer );
			memcpy(visited,visitedc,sizeof(visited));
		}
	}
public:
	//发送者
	int sender;
	//人数
	set<int> cnt;
	int relation[maxn][maxn];
	bool visited[ maxn ] ;
	vector<vector<int>> nodeOfLayer;
	int minNum;
	string input;
};

int main()
{
	//freopen("input.txt","r",stdin);
	arrGraph ag;
	ag.getInput();
	queue<int>q1;
	vector<int>q2;

	ag.getMinNode(q1,q2,0,0,ag.getLayer());
	//ag.outputG();
	cout<<ag.minNum;
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值