暑假是段好时光

集训开始两个周了,一直没有做好总结,导致前两周时间没好好利用,接下来的日子里,要珍惜时间,勤于总结,多多反省,ice加油!!

-----2012年7月23日早

7.23 拓扑排序

定义:
拓扑排序,是指将一个有向无环图E(G)中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v>∈E(G),则u在线性序列中出现在v之前的排列方式.
本质:
对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前.
通常,满足这种线性次序的序列叫做拓扑序列.

特点(性质):
①若将图中顶点按拓扑次序排成一行,则图中所有的有向边均是从左指向右的.
②若图中存在有向环,则不可能使顶点满足拓扑次序.
③一个有向无环图的拓扑序列通常表示某种方案切实可行.
④一个有向无环图可能有多个拓扑序列.
//HDU3342 Legal  or Not
#include<stdio.h>
#include<vector>
#include<string.h>
#include<iostream>
#define N 105
using namespace std;
int map[N][N], XX[N];
int main(){
	int n , m , i , j , a , b ;
	while( cin >> n >> m , n ){
		memset( map, 0, sizeof(map) );
		memset( XX , 0, sizeof(XX) );
		for( i=1 ; i<=m ; i++){
			cin >> a >> b ;
			if(map[a][b])
                continue ;
			map[a][b] = 1 ;
			XX[b]++ ;
		}
		int flag = 1 ;
		for( int T=0 ; T<n ; T++){
            for( i = 0 ;i < n ; i++ ) {
                if( XX[i]==0 ) {
                    XX[i]--;
                    for(j = 0 ; j < n ; j++ )
                        if(map[i][j])
                            XX[j]-- ;
                    break ;
                }
            }
            if(i>=n){
                flag = 0 ;
                break ;
            }
		}
		if(!flag)    puts("NO");
		else         puts("YES");
	}
	return 0;
}
//HDU1285 确定比赛名次
#include <string.h>
#include <iostream>
using namespace std;
int map[502][502], indegree[502], m, n, pur[502];

void topsort(){
	int i , j , k=1;
	for(i=1; i<=n; i++) {
		for(j=1; j<=n; j++) {
			if(indegree[j]==0) {
				indegree[j]--;
				pur[k++] = j;
				for(int x=1; x<=n; x++)
					if(map[j][x])
						indegree[x]--;
				break;
			}
			if(j>n) {
				cout<<"存在环"<<endl;
				return ;
			}
		}
	}
}
int main(){
	int i, j;
	while(cin>>n>>m)	{
		memset(map,0,sizeof(map));
		memset(indegree,0,sizeof(indegree));
		int a, b;
		for(i=1; i<=m; i++){
			cin>>a>>b;
			if(!map[a][b]){
				map[a][b] = 1;
				indegree[b]++;
			}
		}
		topsort();
		for(i=1; i<=n; i++)
			if(i!=n)
				cout<<pur[i]<<" ";
			else
				cout<<pur[i]<<endl;
	}
	return 0 ;
}
//HDU 2647 Reward
#include<stdio.h>
#include<vector>
#include<string.h>
#include<iostream>
#define N 10005
using namespace std;
vector<int>::iterator it;
int main(){
	int n , m , i , a , b ;
	while( cin >> n >> m){
		int  XX[N] = {0} ;
		vector <int> map[N] ;
		for( i=0 ; i<m ; i++){
			cin >> a >> b;
			map[b].push_back(a);
			XX[a]++ ;
		}
		int T = n , flag = 1 , sum=0 , mon = 888 ;
		while(T){
		    int Temp[N]={0} , k = 0 ;
            for( i = 1 ;i <= n ; i++ ){
                if( XX[i]==0 ){
                    T-- ;
                    XX[i]--;
                    Temp[k++] = i ;
                    sum += mon ;
                    if(T== 0) goto End;
                }
            }
            for( i = 0 ;i < k ; i++ )
                for( it = map[Temp[i]].begin() ; it < map[Temp[i]].end() ; it++ )
                        XX[*it]-- ;
            if(!k){
                flag = 0 ;
                break ;
            }
            mon++ ;
		}
		End:;
		if(!flag)   puts("-1");
		else   printf("%d\n",sum);
	}
	return 0;
}

7.24上午 拓扑排序

艾玛,来就搞这个,搞了一上午,终于熟练了一点,还得多写代码,提高代码能力,加油
// POJ1094 + NYOJ349 Sorting It All Out
//#define Judge_Online
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define N 27
using namespace std;
int ABC[N][N], Union[N] , Copy_Union[N] ,Ans[N];
bool flag1[N];
int n, m, flag ,Count , Count2;
void Set(char a, char b){
    int x = a-'A', y = b-'A';
    if(ABC[x][y]==0)  {
        ABC[x][y] = 1 ;
        Union[y]++ ;
        Count++;
        if(!flag1[x]){
            flag1[x] = 1 ;
            Count2++;
        }
        if(!flag1[y]){
            flag1[y] = 1 ;
            Count2++;
        }
    }
    memset(Ans,0,sizeof(Ans));
    memcpy( Copy_Union, Union, sizeof(Union) );
    int xx=Count2 ,temp = 0, aaa=0 ;
    bool sss[N] = {0} ;
    while(xx){
        int Temp[N]={0}, k=0 ;
        for(int i=0 ; i<n ; i++)
            if(!Copy_Union[i] && flag1[i]){
                Copy_Union[i]--;
                xx--;
                Ans[aaa++] = i ;
                Temp[k++] = i ;
                sss[i]=1;
                if(xx==0)
                    break ;
            }
        if(!k){
            flag = 1;
            return ;
        }
        if(k!= 1 )
            temp = 1 ;
 //       printf("%d %d  %d\n",Count2 ,xx , k) ;
        for(int i=0 ; i<k ; i++)
            for(int j=0 ; j<n ; j++ )
                if(ABC[Temp[i]][j] && !sss[j])
                    Copy_Union[j]--;
    }
    End:;
    if(!temp){
        for(int i=0 ; i<n ; i++)
            if(!sss[i])
                temp = 1 ;
        if(!temp)
            flag = 2;
    }
}
int main(){
    #ifdef Judge_Online
	freopen( "Input.txt" ,"r", stdin );
    #endif
    char a, b, op;
    while( cin >> n >> m ,m+n ){
        memset(ABC,0,sizeof(ABC));
        memset(Union,0,sizeof(Union));
        memset(flag1,0,sizeof(flag1));
        Count = 0;
        Count2 = 0;
        flag = 0;
        for( int i=1 ; i<=m ; i++ ){
            getchar();
            cin >> a >> op >> b;
            if(flag==0)
                Set( a, b);
        }
        if(!flag)
            puts("Sorted sequence cannot be determined.");
        else if(flag==1)
            printf("Inconsistency found after %d relations.\n",Count);
        else{
            printf("Sorted sequence determined after %d relations: ",Count);
            for(int i=0 ; i<n ; i++)
                printf("%c",Ans[i]+'A');
            printf(".\n");
        }
    }
	return 0;
}

7.24下午 最小生成树

进军 最小生成树,计划进行时间为 两天,加油!!

#define Judge_Online
#include<stdio.h>
#include<string.h>
#include<iostream>
#define N 503
#define MAX 99999999
using namespace std;
int map[N][N], n , MinSum , LowCost[N];
void Prim(){
	for(int i=1;i<=n;i++)               //初始化
		LowCost[i]=map[1][i];
	LowCost[1]=0;                    //等于零表示在最小路径集合中
	for(int i=2;i<=n;i++){
		int k,minn=MAX;
		for(int j=2;j<=n;j++) {          //找最小边
			if(LowCost[j]<minn&&LowCost[j]!=0){
				minn=LowCost[j];
				k=j;
			}
		}
		MinSum += minn ;
		LowCost[k]=0;
		for(int j=2;j<=n;j++)
			if(map[k][j]<LowCost[j])
				LowCost[j]=map[k][j];
	}
}
int main(){
    #ifdef Judge_Online
    freopen( "Input.txt", "r" , stdin );
    #endif
    int cases, m, j, x, y, Min;
    scanf( "%d", &cases );
    while( cases-- ){
        memset( map , 0, sizeof(map));
        Min = MAX ;
        scanf( "%d%d" , &n, &m );
        for( int i=0 ; i<m ; i++){
            scanf( "%d%d%d" , &x, &y, &j);
            map[x][y] = j;
            map[y][x] = j;
        }
        for( int i=0 ; i<n ; i++ ){
            scanf( "%d" , &j);
            Min = min( Min , j );
        }
        MinSum = 0;
        Prim();
        printf( "%d\n" , MinSum+Min );
    }
	return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值