您的位置:首页 > 产品设计 > UI/UE

POJ 3114 Countries in War / HDU 2767 Proving Equivalences 强连通分量模板

2014-02-11 18:47 417 查看
强连通分量:若在一个点集U中,对于任意两个点u,v(u,v∈U && u != v),即存在一条从 u 到 v 的路径,也存在一条从 v 到 u 的路径,则称此集合为强连通分量。

Taijan算法:

借助 index[ ] 和 rv[ ] 两个数组,rv[ u ] 记录DFS访问 u 时 的时间戳,index[ u ] 记录在DFS树中,u及其子孙能通过反向边连接到的正在等待DFS回溯的点中rv[]的最小值,也可以理解成最远的祖先。

若在回溯过程中有 index[ u ]  != rv[ u ] , 并将其压入栈中。

若在回溯过程中有 index[ u ] == rv[ u ],则  u 为其所在的强连通分量中第一个被访问的点。此时应将栈中的u及在u之后被压入的点弹出。

POJ 3114 :强连通分量 + 最短路。不再赘述。

HDU 2767:若图已联通,则输出0。否则统计各连通分量形成的缩点的出入度,id,od,输出max(id,od).

POJ 3114 

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>

#define LL long long
#define ULL unsigned long long
#define PI (acos(-1.0))
#define EPS (1e-10)
#pragma comment(linker,"/STACK:102400000,1024000")

using namespace std;

const int MAX = (1<<30);

struct P
{
int u,v,w;
}p[250010];

struct N
{
int v,next;
}e[250100];

int index[20100];
int head[20100];
int rv[20100];
int ty[20100];
int ry[20100];

int st[20100];

bool id[20100];
bool od[20100];

int Top,Time,St_Top;

void link(int u,int v)
{
e[Top].next = head[u];
e[Top].v = v;
head[u] = Top++;
}

void dfs(int s)
{
rv[s] = index[s] = Time++;
st[St_Top++] = s;

for(int p = head[s]; p != -1; p = e[p].next)
{
if(rv[e[p].v] == -1)
{
dfs(e[p].v);
index[s] = min(index[s],index[e[p].v]);
}
else if(ty[e[p].v] == -1)
{
index[s] = min(index[s],rv[e[p].v]);
}
}

if(index[s] == rv[s])
{
ry[Top] = s;
while(true)
{
St_Top--;
int x = st[St_Top];
ty[x] = Top;
if(x == s)
break;
}
Top++;
}
}

int dis[510];

void sp(int u,int v,int n,int m)
{
if(ty[u] == ty[v])
{
printf("0\n");
return ;
}

int i,j;
bool mark;

for(i = 0;i < Top; ++i)
{
dis[i] = MAX;
}

dis[ty[u]] = 0;

for(i = 0;i < Top; ++i)
{
mark = true;
for(j = 0;j < m; ++j)
{
if(ty[p[j].v] != ty[p[j].u] && dis[ty[p[j].u]] + p[j].w < dis[ty[p[j].v]])
{
dis[ty[p[j].v]] = dis[ty[p[j].u]] + p[j].w;
mark = false;
}
}
if(mark)
break;
}

if(dis[ty[v]] == MAX)
{
printf("Nao e possivel entregar a carta\n");
}
else
{
printf("%d\n",dis[ty[v]]);
}

}

int main()
{
int n,m,i,u,v;

while(scanf("%d %d",&n,&m) && n)
{
memset(head,-1,sizeof(int)*(n+3));
memset(rv,-1,sizeof(int)*(n+3));
memset(ty,-1,sizeof(int)*(n+3));

Top = 0;

for(i = 0; i < m; ++i)
{
scanf("%d %d %d",&p[i].u,&p[i].v,&p[i].w);
link(p[i].u,p[i].v);
}

Top = 0,Time = 0,St_Top = 0;

for(i = 1; i <= n; ++i)
{
if(rv[i] == -1)
{
dfs(i);
}
}

int k;

scanf("%d",&k);

while(k--)
{
scanf("%d %d",&u,&v);
sp(u,v,n,m);
}
printf("\n");
}
return 0;
}


HDU 2767 :

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>

#define LL long long
#define ULL unsigned long long
#define PI (acos(-1.0))
#define EPS (1e-10)
#pragma comment(linker,"/STACK:102400000,1024000")

using namespace std;

const int MAX = (1<<30);

struct N
{
int v,next;
}e[50100];

int index[20100];
int head[20100];
int rv[20100];
int ty[20100];
int ry[20100];

int st[20100];

bool id[20100];
bool od[20100];

int Top,Time,St_Top;

void link(int u,int v)
{
e[Top].next = head[u];
e[Top].v = v;
head[u] = Top++;
}

void dfs(int s)
{
rv[s] = index[s] = Time++;
st[St_Top++] = s;

for(int p = head[s]; p != -1; p = e[p].next)
{
if(rv[e[p].v] == -1)
{
dfs(e[p].v);
index[s] = min(index[s],index[e[p].v]);
}
else if(ty[e[p].v] == -1)
{
index[s] = min(index[s],rv[e[p].v]);
}
}

if(index[s] == rv[s])
{
ry[Top] = s;
while(true)
{
St_Top--;
int x = st[St_Top];
ty[x] = Top;
if(x == s)
break;
}
Top++;
}
}

int main()
{
//freopen("b.in","r",stdin);

int n,m,i,p,u,v,T;

scanf("%d",&T);

while(T--)
{
scanf("%d %d",&n,&m);

memset(head,-1,sizeof(int)*(n+3));
memset(rv,-1,sizeof(int)*(n+3));
memset(ty,-1,sizeof(int)*(n+3));

Top = 0;

for(i = 0; i < m; ++i)
{
scanf("%d %d",&u,&v);
link(u,v);
}

Top = 0,Time = 0,St_Top = 0;

for(i = 1; i <= n; ++i)
{
if(rv[i] == -1)
{
dfs(i);
}
}

memset(id,false,sizeof(bool)*(Top+3));
memset(od,false,sizeof(bool)*(Top+3));

for(i = 1;i <= n; ++i)
{
for(p = head[i]; p != -1; p = e[p].next)
{
if(ty[i] != ty[e[p].v])
{
od[ty[i]] = true;
id[ty[e[p].v]] = true;
}
}
}

int a1,a2;

for(i = 0,a1 = 0,a2 = 0;i < Top; ++i)
{
if(od[i] == false)
{
a1++;
}
if(id[i] == false)
{
a2++;
}
}

if(Top == 1)
{
printf("0\n");
}
else
{
if(a1 > a2)
printf("%d\n",a1);
else
printf("%d\n",a2);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: