图论|[BZOJ1894][COCI2011-2012第7场]总统演讲
题目描述 临近选举,总统要在城市1和城市2举行演讲。他乘汽车完成巡回演讲,从1出发,途中要经过城市2,最后必须回到城市1.特勤局对总统要经过的所有城市监控。为了使得费用最小,必须使得监控的城市最少。求最少要监控的城市。 一共有N个城市,有M条有向边。(0<=N,M<=200)。有N从1出发途中要经过2,最后要回到1的路线中最少要经过的点的数目。
输入 第一行包含2个整数N,M。N表示城市的数目,M表示有向边的数目。 接下来m行,每行两个数A,B,表示从A到B有一条有向边。
输出: 最少要访问的城市的数量。
样例输入 6 7 1 3 3 4 4 5 5 1 4 2 2 6 6 3
5 8
1 3
5 2
3 4
2 4
4 3
4 2
3 1
1 5
样例输出 6
4
题解:做两次DFS,第一次求出1至2的最少点数, 第二次求出2至1的最少点数
输入 第一行包含2个整数N,M。N表示城市的数目,M表示有向边的数目。 接下来m行,每行两个数A,B,表示从A到B有一条有向边。
输出: 最少要访问的城市的数量。
样例输入 6 7 1 3 3 4 4 5 5 1 4 2 2 6 6 3
5 8
1 3
5 2
3 4
2 4
4 3
4 2
3 1
1 5
样例输出 6
4
题解:做两次DFS,第一次求出1至2的最少点数, 第二次求出2至1的最少点数
#include
#include
#include
#include
#include
#include
using namespace std;
const int INF=0x3f3f3f3f;
const int N=205;
int n, m, ans, sum, fir[N];
struct node{ int e, next;
}edge[N];
bool vis1[N], vis2[N];
void Link( int s, int e, int i ) {
edge[i].e=e;
edge[i].next=fir[s];
fir[s]=i;
} void DFS2( int r ) {
if( sum>=ans ) return;
if( r==1 ) { ans=sum;
return;
}
vis2[r]=1;
if( !vis1[r] ) sum++;
//vis1记录过的点可以重复走, 但不能重复累加
for( int i=fir[r];
i;
i=edge[i].next )
if( !vis2[edge[i].e] ) DFS2( edge[i].e );
vis2[r]=0;
if( !vis1[r] ) sum--;
} void DFS1( int r) {
if( sum>=ans ) return;
if( r==2 ) { DFS2( r );
return;
}
vis1[r]=1;
sum++;
for( int i=fir[r];
i;
i=edge[i].next )
if( !vis1[edge[i].e] ) DFS1( edge[i].e );
//不能重复走
vis1[r]=0;
sum--;
} int main() {
scanf( "%d%d", &n, &m );
for( int i=1;
i<=m;
i++ ) {
int s, e;
scanf( "%d%d", &s, &e );
Link( s, e, i );
}
ans=INF;
DFS1( 1 );
printf( "%d\n", ans );
return 0;
}
推荐阅读
- 图论算法遍历基础
- 图论|POJ1364 King 差分约束
- 图论|tarjan算法之——割点和桥
- 双连通分量|【算法竞赛进阶指南】(图论) Network 边双连通分量
- 图论|【启发式合并】例题 CodeForces-600E(子树颜色 树上众数)+ CodeForces - 1009F(每层节点数的众数)+ CSU - 1811(去边后,求颜色并集大小)
- 图论|Codeforces Round #316 (Div. 2) D. Tree Requests
- 图论(平面图的对偶图)
- #|图论 —— 网络流 —— 最小割 —— 平面图与对偶图
- 图 ->四分树
- 计算机图论中查找路径算法分析线路布局