题目描述

Nowadays, "Circle of Friends" is a very popular social networking platform in WeChat. We can share our life to friends through it or get other's situation.

Similarly, in real life, there is also a circle of friends, friends would often get together communicating and playing to maintain friendship. And when you have difficulties, friends will generally come to help and ask nothing for return.

However, the friendship above is true friend relationship while sometimes you may regard someone as your friend but he doesn't agree.In this way when you ask him for help, he often asks you for a meal, and then he will help you.

If two people think they are friends mutually,they will become true friend,then once one of them has a problem or makes a query, the other one will offer help for free.What's more,if one relationship is similar to “A regards B as friend, B regards C as friend
and C regards A as friend”,they will make a friends circle and become true friends too with each other. Besides, people will not ask those who they don’t regard as friends for help. If one person received a question and he can not solve it, he will ask his
friends for help. 

Now, Nias encounters a big problem, and he wants to look for Selina's help. Given the network of friends, please return the minimum number of meals Nias must offer. Of course Nias is lavish enough, so he will pay for all the meals in the network of friends.

输入

The first line of input contains an integer T, indicating the number of test cases (T<=30).

For each test case, the first line contains two integers, N and M represent the number of friends in the Nias’s network and the number of relationships in that network. N and M are less than 100000 and you can assume that 0 is Nias and n-1 is Selina.

Next M lines each contains two integers A and B, represent a relationship that A regards B as his friend, A and B are between 0 and n-1.

输出

For each test case, please output the minimum number of meals Nias need to offer; if Nias can’t get Selina’s help, please output -1.

样例输入

3
4 4
0 1
1 2
2 1
2 3

3 3
0 1
1 2
2 1

3 1
0 1

样例输出

2
1
-1

题解

首先,深度优先求有向图强连通分量(Tarjan)算法

其次,构图,所构造出来的新图是一个拓扑图

最后,spfa求最短路径.

知识点:

spfa适用于稀疏图最短路径,dijstra适合稠密图最短路.

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 7;
int N, M;
struct Edge{
	int to, next;
}e[maxn*2];
int ei,g[maxn];
void push_back(int f, int t){
	e[++ei].to = t;
	e[ei].next = g[f];
	g[f] = ei;
}
int ti, pre[maxn], low[maxn],num[maxn],sccNo;
int a[maxn];
struct Stack{
	int a[maxn];
	int i;
	void init(){ i = 0; }
	void push(int x){a[i++] = x;}
	int pop(){return a[--i];}
}sta;
void dfs(int now){
	pre[now] = low[now] = ++ti;
	sta.push(now);
	for (int i = g[now]; i; i = e[i].next){
		int t = e[i].to;
		if (pre[t] == 0)dfs(t), low[now] = min(low[now], low[t]);
		else if (num[t] == 0)low[now] = min(low[now], pre[t]);
	}
	if (pre[now] == low[now]){
		++sccNo;
		while (true){
			int x = sta.pop();
			num[x] = sccNo;
			if (x == now)break;
		}
	}
}
void newGraph(){
	memset(a, 0, sizeof(int)*(1+sccNo));
	for (int i = 0; i < N; i++){
		for (int j = g[i]; j; j = e[j].next){
			int t = e[j].to;
			if (num[i] ^ num[t]){
				e[++ei].next = a[num[i]];
				e[ei].to = num[t];
				a[num[i]] = ei;
			}
		}
	}
}
struct Q{
	int a[maxn], head, rear;
	bool has[maxn];
	void init(){ head = rear = 0; memset(has, 0, sizeof(int)*(sccNo+1)); }
	void enq(int x){ a[rear] = x; rear = (rear + 1) % maxn; has[x] = 1; }
	int deq(){ int ans = a[head]; head = (head + 1) % maxn; has[ans] = 0; return ans; }
}q;
int dis[maxn];
void spfa(){
	q.init();
	q.enq(num[0]);
	memset(dis, 0x34, sizeof(int)*(1 + sccNo));
	dis[num[0]] = 0;
	while (q.head^q.rear){
		int now = q.deq();
		for (int i = a[now]; i; i = e[i].next){
			int t = e[i].to;
			if (dis[t] > dis[now] + 1){
				dis[t] = dis[now] + 1;
				if (q.has[t]== false){
					q.enq(t);
				}
			}
		}
	}
	if (dis[num[N - 1]] == 0x34343434)printf("-1\n");
	else printf("%d\n", dis[num[N - 1]]);
}
int main(){
	freopen("in.txt", "r", stdin);
	int T; scanf("%d", &T);
	while (T--){
		scanf("%d%d", &N, &M);
		ei = 0, memset(g, 0, sizeof(int)*N);
		while (M--){
			int x, y; scanf("%d%d", &x, &y);
			push_back(x, y);
		}
		ti = 0, memset(pre, 0, sizeof(int)*N), memset(num, 0, sizeof(int)*N);
		sta.init(), sccNo = 0;
		for (int i = 0; i < N; i++)if (pre[i] == 0)dfs(i);
		newGraph();
		spfa();
	}
	return 0;
}

东大oj-1591 Circle of friends的更多相关文章

  1. 东大OJ 2SAT 异或

    看了十年才懂懂了十年才会会了十年才会写写了十年才写完写完了十年才能改对 #include<stdio.h> #include<string.h> struct res{ int ...

  2. 东大OJ-Max Area

    1034: Max Area 时间限制: 1 Sec  内存限制: 128 MB 提交: 40  解决: 6 [提交][状态][讨论版] 题目描述 又是这道题,请不要惊讶,也许你已经见过了,那就请你再 ...

  3. 西南民大oj(两园交求面积)

    西南民大oj:http://www.swunacm.com/acmhome/welcome.do?method=index 我的几何不可能那么可爱 时间限制(普通/Java) : 1000 MS/ 3 ...

  4. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  5. [翻译svg教程]svg中的circle元素

    svg中的<circle> 元素,是用来绘制圆形的,例如 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= ...

  6. [C#] 逆袭——自制日刷千题的AC自动机攻克HDU OJ

    前言 做过杭电.浙大或是北大等ACM题库的人一定对“刷题”不陌生,以杭电OJ为例:首先打开首页(http://acm.hdu.edu.cn/),然后登陆,接着找到“Online Exercise”下的 ...

  7. oj Rapid Typing

    import bs4 import requests import urllib2 import time import base64 session=requests.Session() respo ...

  8. 在线OJ实用技巧(转载)

    1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long long或__int64型(两个下 ...

  9. 设计一个程序,程序中有三个类,Triangle,Lader,Circle。

    //此程序写出三个类,triangle,lader,circle:其中triangle类具有类型为double的a,b,c边以及周长,面积属性, //具有周长,面积以及修改三边的功能,还有判断能否构成 ...

随机推荐

  1. iNeedle系统之国舜项目

    一.简介 本周公司接了一个小项目,是给北京国舜科技股份有限公司做一个HTTP相关的小功能产品.大概实现功能是将交换机的源数据通过解析,分析出HTTP包配对的request和response头,并把每对 ...

  2. linux创建用户、设置密码、修改用户、删除用户

    创建用户.设置密码.修改用户.删除用户:useradd testuser 创建用户testuserpasswd testuser 给已创建的用户testuser设置密码说明:新创建的用户会在/home ...

  3. Configure Ocserv on CentOS 6

    Configure Ocserv on CentOS 6 Table of Contents 1. Install ocserv 2. Configure ocserv 3. How to host ...

  4. plsql+绿色版oracle连接远程数据库配置及提示缺少msvcr71.dll解决方法

    之前一直用的sqldeveloper连接oracle数据库,这个免费而且也是官方出品,除了体积略大启动略慢外,也没什么不好的.. 一次偶然机会决定试一下plsql,整理一下安装资料,需要本地oracl ...

  5. ListView的基础应用

    在写完基础的布局之后,下一课我们会学习一下如何使用Android中一个非常重要,但是对于新手略有困难的ListView,甚至很久以前都有人说过,会不会写ListView是Android能否入门的第一步 ...

  6. git 学习使用总结二(远程仓库操作)

    这篇文章仅供自己以后翻阅加深记忆,要系统的学习 git 教程(中文版),请移步到 liaoxuefeng.com 学习 git 教程部分. 我使用的是 windows 系统,所以使用 Git Bash ...

  7. CSS Sprite雪碧图应用

    在写网页过程中,会遇到这种需要使用多个小图标: 如上图中的「女装」文字左边的图标.容易想到的解决方法是为每张图片加入<img>标签,但这样做会增加HTTP请求数量,影响网站加载速度.比这更 ...

  8. No 'Access-Control-Allow-Origin' header is present on the requested resource.

    今天做一个AJAX案例时,浏览器监控到如下错误: XMLHttpRequest cannot load http://54.169.69.60:8081/process_message. No 'Ac ...

  9. (一)观察者模式-C++实现

    观察者模式: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新. 它有四种角色: 主题(Subject):一个接口,规定了具体主题需要实现的方法. ...

  10. Java中的链表数据结构

    首先,我们来定义一个链表的数据结构,如下: 1 public class Link { 2 private int value; 3 private Link next; 4 public void ...