zoukankan      html  css  js  c++  java
  • uva-208-枚举-并查集

    题意:

    给你一个图,从1到指点的点有多少种不同的路径,用了并查集剪枝,如果当前节点的根不是指定的节点,直接返回,会超时

    time limit了俩次,wa了俩次,PE俩次

    #include <iostream>
    #include <stdio.h>
    #include<memory.h>
    using namespace std;
    
    #define null NULL
    const int N = 25;
    int final = -1;
    int mindex[N];
    int map[N][N];
    int vis[N];
    int res[N];
    int n, m;
    int total = 0;
    
    int set[N];
    int p(int s)
    {
    	return set[s] == s ? s : set[s] = p(set[s]);
    }
    void add(int s, int e)
    {
    	int p1 = p(s);
    	int p2 = p(e);
    	int t = s == final ? s : e;
    	if (t != final)
    		t = p1 == final ? p1 : p2;
    	if (t == final)
    	{
    		set[t] = final;
    		set[p1] = final;
    		set[p2] = final;
    		set[s] = final;
    		set[e] = final;
    		return;
    	}
    	if (p1 < p2)
    	{
    		set[p2] = p1;
    	}
    	else
    	{
    		set[p1] = p2;
    	}
    }
    
    void read()
    {
    	for (int i = 0; i < N; i++)
    		set[i] = i;
    
    	int s, e;
    	while (cin >> s >> e)
    	{
    		if (s == 0 && e == 0)
    			return;
    		map[s][mindex[s]++] = e;
    		map[e][mindex[e]++] = s;
    		add(s, e);
    	}
    }
    
    void sort(int l, int t, int a[])
    {
    	for (int i = 0; i < t; i++)
    	{
    		for (int j = 1; j < t - i; j++)
    		{
    			if (a[j - 1] > a[j])
    			{
    				int t = a[j - 1];
    				a[j - 1] = a[j];
    				a[j] = t;
    			}
    		}
    	}
    }
    
    void dfs(int cur, int rl)
    {
    	if (cur == final)
    	{
    		printf("%d",res[0]);
    		for (int i = 1; i <= rl; i++)
    		{
    			printf(" %d", res[i]);
    		}
    		cout << endl;
    		++total;
    		return;
    	}
    	if (p(cur) != final)
    		return;
    	for (int i = 0; i < mindex[cur]; i++)
    	{
    		if (vis[map[cur][i]] == 0)
    		{
    			vis[map[cur][i]] = 1;
    			res[rl + 1] = map[cur][i];
    			dfs(map[cur][i], rl + 1);
    			vis[map[cur][i]] = 0;
    		}
    	}
    }
    
    int main(int argc, char* argv[])
    {
    	freopen("C:\Users\zzzzz\Desktop\1.txt", "r", stdin);
    	int t = 1;
    	string str =
    			"There are %d routes from the firestation to streetcorner %d.";
    	while (cin >> final)
    	{
    		memset(map, 0, sizeof(map));
    		memset(mindex, 0, sizeof(mindex));
    		memset(vis, 0, sizeof(vis));
    		read();
    		total = 0;
    		cout << "CASE " << t << ":" << endl;
    		for (int i = 1; i <= final; i++)
    			sort(i, mindex[i], map[i]);
    		vis[1] = 1;
    		res[0] = 1;
    		dfs(1, 0);
    		printf(str.c_str(), total, final);
    		cout<<endl;
    		++t;
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    第一个反汇编程序
    边缘网关协议(BGP)
    Servlet 学习小结之doPost()方法和doGet()方法
    extern "C"
    工欲善其事 必先利其器
    我是一个混蛋程序员
    KMP 算法——C
    二分查找——C语言
    大整数加法——C语言
    子字符串查找——C语言
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/7672572.html
Copyright © 2011-2022 走看看