↓ Skip to main content
  1. Posts/

whust 2016 warm up E ||codeforces 689 B. Mike and Shortcuts (spfa)

·563 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

cf689B题目链接

题意:n点。。点i到点j的代价是|i-j|..给出n条近路。。。a[i]表示点i到a[i]的代价为1(注意近路不一定就近)

思路:一开始建边卡了一下。。。实际上只要连相邻的就好了。。。然后边表只开了2N蠢哭。。。实际上应该3M…因为连相邻的边是双向的。。。再加上近路的单向。。。然后spfa就好了。。。。

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年07月18日 星期一 13时33分18秒
  4File Name :code/2016whust/F.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=2E5+7;
 34int n;
 35int a[N];
 36bool inq[N];
 37int d[N];
 38int head[N];
 39int cnt;
 40
 41
 42struct Edge
 43{
 44    int v;
 45    int w;
 46    int nxt;
 47}edge[8*N];
 48
 49void addedge( int u,int v,int w)
 50{
 51    edge[cnt].v = v;
 52    edge[cnt].w = w;
 53    edge[cnt].nxt = head[u];
 54    head[u] = cnt;
 55    cnt++;
 56}
 57void init()
 58{
 59    ms(head,-1);
 60    cnt = 0 ;
 61}
 62void spfa( int s)
 63{
 64    ms(inq,false);
 65    ms(d,0x3f);
 66    queue<int>q;
 67    q.push(s);
 68    inq[s] = true;
 69    d[s] =  0;
 70
 71    while (!q.empty())
 72    {
 73	int u = q.front();
 74//<	cout<<"u:"<<u<<endl;
 75	q.pop();
 76	inq[u] = false;
 77
 78	for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt)
 79	{
 80	    int v = edge[i].v;
 81	    int w = edge[i].w;
 82	    if (d[v]>d[u]+w)
 83	    {
 84		d[v] = d[u] + w;
 85		if (inq[v]) continue;
 86		inq[v] = true;
 87		q.push(v);
 88	    }
 89//	    if (a[u]==v&&d[v]>1)
 90//	    {
 91//		d[v] = 1;
 92//		if (inq[v]) continue;
 93//		inq[v] = true;
 94//		q.push(v);
 95//	    }
 96
 97	}
 98    }
 99}
100int main()
101{
102	#ifndef  ONLINE_JUDGE
103	freopen("code/in.txt","r",stdin);
104  #endif
105
106	cin>>n;
107	init();
108	for ( int i = 1 ; i <= n ; i++)
109	{
110	    scanf("%d",&a[i]);
111	    if (a[i]!=i)
112	    addedge(i,a[i],1);
113//	    addedge(1,i,i-1);
114//	    addedge(i,1,i-1);
115//	    else addedge(i,a[i],0);
116	}
117	for ( int i = 1;  i <= n-1 ; i++)
118	{
119	    addedge(i,i+1,1);
120	    addedge(i+1,i,1);
121	}
122
123	spfa(1);
124
125	for ( int i = 1 ; i <= n ; i++) printf("%d ",d[i]);
126
127
128  #ifndef ONLINE_JUDGE
129  fclose(stdin);
130  #endif
131    return 0;
132}

Related

BZOJ 1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 (spfa)

·1064 words·3 mins
1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 250 Solved: 178 [Submit][Status][Discuss] Description # A crime has been comitted: a load of grain has been taken from the barn by one of FJ’s cows. FJ is trying to determine which of his C (1 <= C <= 100) cows is the culprit. Fortunately, a passing satellite took an image of his farm M (1 <= M <= 70000) seconds before the crime took place, giving the location of all of the cows. He wants to know which cows had time to get to the barn to steal the grain. Farmer John’s farm comprises F (1 <= F <= 500) fields numbered 1..F and connected by P (1 <= P <= 1,000) bidirectional paths whose traversal time is in the range 1..70000 seconds (cows walk very slowly). Field 1 contains the barn. It takes no time to travel within a field (switch paths). Given the layout of Farmer John’s farm and the location of each cow when the satellite flew over, determine set of cows who could be guilty. NOTE: Do not declare a variable named exactly ’time’. This will reference the system call and never give you the results you really want.

BZOJ 1631: [Usaco2007 Feb]Cow Party (SPFA)

·906 words·2 mins
1631: [Usaco2007 Feb]Cow Party # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 670 Solved: 493 [Submit][Status][Discuss] Description # 农场有N(1≤N≤1000)个牛棚,每个牛棚都有1只奶牛要参加在X牛棚举行的奶牛派对.共有M(1≤M≤100000)条单向路连接着牛棚,第i条路需要Ti的时间来通过.牛们都很懒,所以不管是前去X牛棚参加派对还是返回住所,她们都采用了用时最少的路线.那么,用时最多的奶牛需要多少时间来回呢? Input # 第1行:三个用空格隔开的整数.

hdu 3873 Invade the Mars (有限制条件的最短路。。)

·777 words·2 mins
hdu3873题目链接 题意:n个点的图。。。每个点可能被若干其他点保护。。。被保护的意思是。。。如果想访问某个点。。那么必须先访问保护该点的所有点。。。问从点1到点n的最小代价。。 思路:。。一开始写了spfa。。。然后一脸懵逼。。。因为我第一次访问某个点的时候无法保证距离是最短的。。。所以还是上dij吧。。。

uva 10986 Sending email (spfa)

·367 words·1 min
uva10986题目链接 题意:裸的spfa. 思路:模板,1A. 代码实现 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 03时25分27秒 4File Name :code/uva/10986.cpp 5************************************************ */ 6 7#include <cstdio> 8#include <cstring> 9#include <iostream> 10#include <algorithm> 11#include <vector> 12#include <queue> 13#include <set> 14#include <map> 15#include <string> 16#include <cmath> 17#include <cstdlib> 18#include <ctime> 19#define fst first 20#define sec second 21#define lson l,m,rt<<1 22#define rson m+1,r,rt<<1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair < int ,int > 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E4+7; 34int n,m; 35int S,T; 36vector < pi > edge[N]; 37 38int d[N]; 39bool inq[N]; 40bool spfa( int s,int t) 41{ 42 ms(d,0x3f); 43 ms(inq,false); 44 queue<int>q; 45 q.push(s); 46 inq[s] = true; 47 d[s] = 0; 48 49 while (!q.empty()) 50 { 51 int u = q.front(); 52 q.pop(); 53 inq[u] = false; 54 55 int siz = edge[u].size(); 56 57 for ( int i = 0 ; i < siz ; i++) 58 { 59 int v = edge[u][i].fst; 60 if (d[v]>d[u] + edge[u][i].sec) 61 { 62 d[v] = d[u] + edge[u][i].sec; 63 if (inq[v]) continue; 64 inq[v] = true; 65 q.push(v); 66 } 67 } 68 } 69 return d[t]!=inf; 70} 71int main() 72{ 73 #ifndef ONLINE_JUDGE 74 freopen("code/in.txt","r",stdin); 75 #endif 76 ios::sync_with_stdio(false); 77 int TT; 78 cin>>TT; 79 int cas = 0 ; 80 while (TT--) 81 { 82 cin>>n>>m>>S>>T; 83 for ( int i = 0 ; i <= n ; i++) edge[i].clear(); 84 for ( int i = 1 ; i <= m ; i++) 85 { 86 int u,v,w; 87 cin>>u>>v>>w; 88 edge[u].push_back(make_pair(v,w)); 89 edge[v].push_back(make_pair(u,w)); 90 } 91 92 if (spfa(S,T)) 93 { 94 printf("Case #%d: %d\n",++cas,d[T]); 95 } 96 else 97 { 98 printf("Case #%d: unreachable\n",++cas); 99 } 100 101 } 102 103 #ifndef ONLINE_JUDGE 104 fclose(stdin); 105 #endif 106 return 0; 107}

poj 2949 Word Rings (spfa+栈优化)

·1620 words·4 mins
poj2949 题目链接 题意:我们有 n 个 (n<=100000) 字符串,每个字符串都是由 a~z 的小写英文字母组成的字符串。如果字符串 A 的结尾两个字符刚好与字符串 B 的开头两个字符相匹配,那么我们称 A 与 B 能相连(注意:A 能与 B 相连不代表 B 能与 A 相连)。我们希望从给定的字符串中找出一些,使得它们首尾相接形成一个环串(一个串首尾相连也算),我们想要使这个环串的平均长度最长。