zoukankan      html  css  js  c++  java
  • POJ3177Redundant Paths

    转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6762432

    大致题意:

           为了保护放牧环境,避免牲畜过度啃咬同一个地方的草皮,牧场主决定利用不断迁移牲畜进行喂养的方法去保护牧草。然而牲畜在迁移过程中也会啃食路上的牧草,所以如果每次迁移都用同一条道路,那么该条道路同样会被啃咬过度而遭受破坏。

           现在牧场主拥有F个农场,已知这些农场至少有一条路径连接起来(不一定是直接相连),但从某些农场去另外一些农场,至少有一条路可通行。为了保护道路上的牧草,农场主希望再建造若干条道路,使得每次迁移牲畜时,至少有2种迁移途径,避免重复走上次迁移的道路。已知当前有的R条道路,问农场主至少要新建造几条道路,才能满足要求?

    解题思路:

    “使得每次迁移牲畜时,至少有2种迁移途径,避免重复走上次迁移的道路。”就是说当吧F个农场看作点、路看作边构造一个无向图G时,图G不存在桥。

    那么可以建立模型:

           给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图。

    这题是和POJ3352一模一样的题,只不过表述方式不同而已。

    详细解题过程请参考我POJ3352的解题报告,有详细叙述。

    传送门:

    我的POJ3353解题报告:

    http://blog.csdn.net/lyy289065406/article/details/6762370

    看完POJ3353的解题报告,再回来看看本题要注意的一些地方:

    本题和3353最大的区别就是,3353保证了没有重边,而本题有重边。

    而3353的解题报告已经说过,当两点之间出现重边时,就不可以利用Low值去划分【边双连通分量】了,因为此时不同Low值的两点可能属于同一个【边双连通分量】!

    那么如何解决重边的问题?

    1、  构造图G时把重边也考虑进来,然后在划分边双连通分量时先把桥删去,再划分,其中桥的一端的割点归入当前正在划分的边双连通分量。这个处理比较麻烦;

    2、  在输入图G的边时,若出现重边,则不把重边放入图G,然后在划分边双连通分量时依然用Low划分。

    两者相权,当然是第2种方法更好处理了。

    其实用邻接矩阵去存储图G的同学,是无需考虑重边的问题的。

    但是用邻接链表去存储图G的同学就不得不考虑了,因为基本上都是用头插入法在链表中插入边的,所以无法检测重边。而改用尾插入法,则可以在指针从链头移到链尾的同时,顺便加一个判断,出现重边则不再插入,否则插入到尾部。

    //Memory Time 
    //236K   16MS  
    
    #include<iostream>
    using namespace std;
    
    class Node
    {
    public:
    	int id;
    	class Node* next;
    	Node():id(0),next(0){}
    };
    
    class solve
    {
    public:
    	solve(int f,int r):F(f),R(r)
    	{
    		Initial();			
    		Input_Creat();
    		Tarjan(1,-1);		//本题给定的图G为连通的,因此从任意节点开始搜索均可
    		printf("%d\n",BCC_SP_D_E());
    	}
    	~solve()
    	{
    		delete[] DFN;
    		delete[] Low;
    		delete[] degree;
    
    		EmptyList();
    	}
    
    	int min(int a,int b) const{return a<b?a:b;}
    
    	void Initial(void);				//申请存储空间并初始化
    	void Input_Creat(void);			//输入并创建图G
    	void AddEdge(int a,int b);		//向链表插入边a<->b (尾插入法,避免重边)
    
    	void Tarjan(int s,int father);	//计算Low[]数组,用于寻找所有边双连通分量
    	int BCC_SP_D_E(void);			//把每个边双连通分量(BCC)构造为缩点(SP),并计算每个缩点的度数(D)
    									//返回值为使得图G为双连通所需添加的最少的边(E)的数量
    
    	void DelLink(Node* p);			//释放以p为表头的整条链
    	void EmptyList(void);			//释放邻接链表
    
    protected:
    
    	int F;					//the number of islands
    	int R;					//the number of roads
    	Node** LinkHead;		//邻接链表表头
    
    	int TimeStamp;			//(外部)时间戳
    	int* DFN;				//DFN[u]: 结点u的搜索次序(时间戳)
    	int* Low;				//Low[u]: 结点u或u的子树能够追溯到的最早的栈中结点的次序号
    
    	int* degree;			//记录每个缩点的总度数
    };
    
    void solve::Initial(void)
    {
    	LinkHead=new Node*[F+1];
    	for(int i=1;i<=F;i++)
    		LinkHead[i]=0;
    
    	TimeStamp=0;
    	DFN=new int[F+1];
    	Low=new int[F+1];
    	memset(DFN,0,sizeof(int)*(F+1));
    	memset(Low,0,sizeof(int)*(F+1));
    
    	degree=new int[F+1];
    	memset(degree,0,sizeof(int)*(F+1));
    
    	return;
    }
    
    void solve::Input_Creat(void)
    {
    	int a,b;
    	Node* tmp;
    	for(int j=1;j<=R;j++)
    	{
    		scanf("%d %d",&a,&b);
    
    		if(!LinkHead[a])
    			LinkHead[a]=new Node;
    		if(!LinkHead[b])
    			LinkHead[b]=new Node;
    
    		AddEdge(a,b);
    	}
    	return;
    }
    
    void solve::AddEdge(int a,int b)
    {
    	Node* pa=LinkHead[a];
    	Node* p1=new Node;
    	p1->id=b;
    
    	while(pa->next)
    	{
    		pa=pa->next;
    		if(pa->id==p1->id)	//出现重边,重边不插入链表
    			return;
    	}
    	pa->next=p1;
    
    	Node* pb=LinkHead[b];
    	Node* p2=new Node;
    	p2->id=a;
    
    	while(pb->next)			//能执行到这里说明a<->b不是重边
    		pb=pb->next;		//直接搜索到链表尾部插入
    	pb->next=p2;
    
    	return;
    }
    
    void solve::Tarjan(int s,int father)
    {
    	DFN[s]=Low[s]=++TimeStamp;
    	for(Node* p=LinkHead[s]->next;p;p=p->next)
    	{
    		int t=p->id;
    		if(t!=father && DFN[t]<DFN[s])
    		{
    			if(DFN[t]==0)			//s->t为树枝边
    			{
    				Tarjan(t,s);
    				Low[s]=min(Low[s],Low[t]);
    			}
    			else					//s->t为后向边
    			{
    				Low[s]=min(Low[s],DFN[t]);
    			}
    		}
    	}
    	return;
    }
    
    int solve::BCC_SP_D_E(void)
    {
    	for(int i=1;i<=F;i++)
    		if(LinkHead[i])
    		{
    			for(Node* p=LinkHead[i]->next;p;p=p->next)	//枚举图G中每两个连通的点i<->j
    			{											//由于图G为无向图,则连通是双向的
    				int j=p->id;
    				if(Low[i]!=Low[j])		//图G中Low值相同的两个点必定在同一个边双连通分量(即同一个缩点)中
    				{						//检查i、j是否不在同一个缩点中
    
    					degree[Low[i]]++;	//结点i所在的缩点的度+1
    					degree[Low[j]]++;	//结点j所在的缩点的度+1
    				}
    			}
    		}
    	
    	int leave=0;			//记录总度数=1(叶子)的缩点
    	for(int k=1;k<=F;k++)	//枚举各个缩点的度数D
    		if(degree[k]/2==1)	//由于是无向图,因此每个缩点的度都重复计算了2次,除2后才是真实的度数
    			leave++;
    
    	return (leave+1)/2;		//将一棵树连成一个边双连通分量至少需要添加的边数=(叶子节点数+1)/2
    }
    
    void solve::DelLink(Node* p)
    {
    	if(p->next)
    		p=p->next;
    	delete[] p;
    	return;
    }
    
    void solve::EmptyList(void)
    {
    	for(int i=1;i<=F;i++)
    		if(LinkHead[i])
    			DelLink(LinkHead[i]);
    	return;
    }
    
    int main(void)
    {
    	int f,r;
    	while(scanf("%d %d",&f,&r)!=EOF)
    		solve poj3177(f,r);
    
    	return 0;
    }
    

    Sample Input

    7 7

    1 2

    2 3

    3 4

    2 5

    4 5

    5 6

    5 7

     

    7 7

    1 2

    2 3

    3 4

    2 5

    4 5

    3 6

    5 7

     

    6 5

    3 1

    3 2

    3 4

    3 5

    3 6

     

    10 12

    1 2

    2 3

    3 1

    3 4

    4 8

    4 5

    5 6

    6 7

    7 5

    8 9

    9 10

    10 8

     

    10 10

    1 8

    6 3

    7 1

    3 5

    5 2

    2 9

    9 7

    8 4

    4 10

    10 6

     

    10 9

    1 2

    7 4

    9 6

    10 6

    8 4

    3 5

    3 4

    3 6

    1 3

     

    16 22

    1 3

    7 1

    5 1

    12 7

    6 3

    4 7

    8 3

    10 7

    14 6

    11 5

    9 7

    15 4

    2 6

    13 12

    8 2

    2 11

    6 1

    4 11

    1 14

    3 10

    13 16

    13 16

     

    27 35

    1 3

    10 3

    22 3

    15 3

    11 15

    5 15

    12 22

    18 10

    23 11

    7 1

    2 15

    25 1

    14 10

    24 11

    8 2

    19 22

    4 12

    16 4

    13 18

    9 14

    21 13

    6 4

    17 23

    20 17

    17 6

    3 21

    20 3

    9 13

    17 12

    20 18

    2 26

    26 27

    27 8

    2 27

    26 8

     

    75 81

    1 3

    58 3

    37 1

    36 58

    15 36

    9 58

    10 37

    8 1

    44 10

    33 44

    61 8

    54 9

    4 3

    20 44

    53 37

    26 20

    67 54

    71 20

    5 3

    70 54

    45 67

    14 54

    74 67

    41 53

    52 37

    63 53

    31 20

    55 63

    60 55

    40 5

    75 58

    62 31

    68 52

    72 36

    49 9

    66 31

    43 41

    22 52

    35 8

    21 45

    30 15

    11 61

    7 68

    57 30

    12 40

    27 71

    25 40

    46 66

    42 61

    24 37

    29 4

    59 11

    16 74

    47 5

    69 74

    64 59

    56 75

    19 9

    48 56

    23 9

    13 72

    2 43

    32 1

    73 13

    28 7

    6 45

    18 4

    38 42

    50 72

    17 53

    39 50

    51 63

    34 25

    65 64

    67 41

    58 5

    5 27

    75 63

    7 50

    20 18

    38 65

     

    200 250

    1 3

    106 1

    134 1

    157 134

    23 106

    60 134

    44 60

    117 1

    126 1

    11 134

    139 44

    178 3

    97 60

    101 157

    118 44

    30 23

    128 30

    174 3

    108 23

    110 128

    132 157

    92 106

    173 132

    79 106

    82 178

    7 44

    52 79

    74 30

    4 23

    49 7

    164 139

    127 30

    156 4

    65 7

    120 101

    46 97

    112 178

    8 46

    59 60

    198 174

    100 134

    90 92

    192 60

    125 100

    26 178

    19 192

    63 125

    155 126

    70 100

    35 63

    151 126

    165 157

    146 70

    84 157

    141 52

    160 70

    163 8

    38 127

    171 139

    62 101

    133 11

    177 146

    158 125

    41 165

    145 52

    98 30

    5 177

    68 164

    168 173

    107 178

    86 132

    199 127

    136 168

    71 155

    50 128

    189 35

    193 46

    105 70

    195 189

    89 158

    69 177

    190 50

    28 19

    21 92

    93 71

    170 86

    122 21

    131 136

    197 158

    16 108

    33 195

    18 164

    196 141

    94 92

    61 79

    149 26

    169 193

    124 163

    78 189

    147 108

    150 49

    129 70

    77 168

    194 18

    54 100

    140 127

    24 196

    109 158

    2 97

    17 195

    64 28

    115 174

    185 41

    81 141

    45 62

    180 18

    167 109

    27 65

    123 140

    188 77

    91 129

    73 110

    76 173

    14 149

    103 105

    51 11

    57 84

    58 101

    148 193

    43 156

    162 109

    22 61

    179 52

    67 74

    200 117

    6 167

    119 192

    113 41

    184 16

    32 98

    39 160

    75 32

    175 98

    121 78

    183 26

    47 174

    102 79

    83 23

    172 127

    176 74

    138 121

    182 90

    29 156

    153 183

    114 162

    152 47

    15 136

    12 64

    143 155

    161 89

    99 90

    87 114

    25 193

    144 86

    137 64

    135 52

    56 14

    55 112

    20 71

    142 5

    34 126

    116 56

    40 79

    130 89

    187 49

    85 62

    111 136

    191 39

    166 16

    159 120

    13 50

    95 55

    154 33

    96 171

    181 115

    88 21

    80 24

    48 14

    72 21

    31 67

    9 31

    66 143

    37 117

    104 56

    36 86

    42 125

    186 33

    10 184

    53 18

    164 64

    136 63

    77 25

    128 105

    133 147

    130 1

    67 161

    10 132

    190 173

    195 80

    123 1

    70 82

    126 38

    163 7

    193 17

    152 105

    44 24

    168 185

    174 163

    177 40

    79 173

    70 19

    26 60

    198 130

    97 22

    143 67

    97 25

    119 89

    194 163

    188 180

    49 173

    109 71

    4 124

    58 79

    151 178

    74 93

    34 96

    161 65

    167 16

    172 114

    183 14

    46 116

    199 187

    118 175

    109 23

    101 115

    160 114

    110 173

    96 28

    77 182

    27 116

     

    14 16

    1 2

    1 12

    12 2

    3 2

    4 3

    4 5

    4 6

    6 14

    7 14

    7 6

    7 8

    7 9

    10 9

    11 10

    11 13

    13 10

    Sample Output

    2

    2

    3

    2

    0

    3

    2

    4

    16

    32

    2

    [ EXP技术分享博客 ] 版权所有,转载请注明出处: http://exp-blog.com
  • 相关阅读:
    java.lang.ClassNotFoundException: org.springframework.web.util.IntrospectorCleanupListener
    ElasticSearch读取查询结果(search)
    Oracle合并某一列
    Django在Eclipse下配置启动端口号
    Apache部署django项目
    Apache的下载安装(主要说的 64位)及问题
    windows7下怎样安装whl文件(python)
    windows下面安装Python和pip终极教程
    Java 多线程 并发编程 (转)
    数据库水平切分的实现原理解析——分库,分表,主从,集群,负载均衡器(转)
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2172095.html
Copyright © 2011-2022 走看看