HDU 4818 RP problem (高斯消元, 2013年长春区域赛F题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4818
深深地补一个坑~~~
现场赛坑在这题了,TAT。。。。
今天把代码改了下,过掉了,TAT
很明显的高斯消元的模型。
现场一开始想的也大概是对的。
根据度可以得到n个方程,加起来为1是一个方程,有一个是多余的。 加起来就是n个方程。
只可能是无穷解和唯一解的情况。
现场是先求解一遍,然后枚举所有可以加的,不停做高斯消元。
但是因为高斯消元是O(n^3) 的, 再枚举的话就是n^4了。。。。
这样做明显应该超时的,HDU交了这样做也是TLE,,,现场被坑死,一直返回WA, 然后程序就改得不成样子了。。。
其实枚举那个可以省略。
因为改变的就是最后一列。
可以扩展矩阵,在后面多加几列。 然后变化之后,直接就得到了x(n-1)的值。
只需要做一次高斯消元。
代码君:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <queue> 6 #include <map> 7 #include <set> 8 #include <vector> 9 #include <string> 10 #include <math.h> 11 using namespace std; 12 13 #define eps 1e-6 14 const int MAXN=220; 15 double a[MAXN][MAXN],x[MAXN]; 16 int equ,var; 17 18 int Gauss() 19 { 20 int i,j,k,col,max_r; 21 for(k=0,col=0;k<equ&&col<var;k++,col++){ 22 max_r = k; 23 for(i=k+1;i<equ;i++) 24 if(fabs(a[i][col])>fabs(a[max_r][col])) 25 max_r = i; 26 if(fabs(a[max_r][col])<eps)return 0; //无解,有自由变元 27 if(k != max_r){ 28 for(j=col;j<var;j++) 29 swap(a[k][j],a[max_r][j]); 30 swap(x[k],x[max_r]); 31 } 32 x[k]/=a[k][col]; 33 for(j=col+1;j<var;j++)a[k][j]/=a[k][col]; 34 a[k][col] = 1; 35 for(i=0;i<equ;i++) 36 if(i!=k){ 37 x[i] -= x[k]*a[i][k]; 38 for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col]; 39 a[i][col]=0; 40 } 41 } 42 return 1; 43 } 44 45 vector<int>vec[MAXN]; 46 int g[MAXN][MAXN]; 47 int du[MAXN]; 48 int add[MAXN]; 49 50 51 int main() 52 { 53 //freopen("in.txt","r",stdin); 54 //freopen("out.txt","w",stdout); 55 int T; 56 int n,m; 57 scanf("%d",&T); 58 while(T--) 59 { 60 scanf("%d%d",&n,&m); 61 for(int i = 0;i < n;i++) 62 vec[i].clear(); 63 memset(g,0,sizeof(g)); 64 memset(du,0,sizeof(du)); 65 int u,v; 66 while(m--) 67 { 68 scanf("%d%d",&u,&v); 69 if(u == v)continue; 70 g[u][v] = 1; 71 } 72 for(int i = 0;i < n;i++) 73 { 74 for(int j = 0;j < n;j++) 75 if(j != i && g[i][j]) 76 { 77 du[i]++; 78 vec[j].push_back(i); 79 } 80 } 81 equ = var = n; 82 for(int i = 0;i < n;i++) 83 x[i] = 0; 84 memset(a,0,sizeof(a)); 85 for(int i = 0;i < n;i++) 86 { 87 a[i][i] = -1; 88 int sz = vec[i].size(); 89 for(int j = 0;j < sz;j++) 90 { 91 int v = vec[i][j]; 92 if(i == v)continue; 93 a[i][v] = 1.0 / du[v]; 94 } 95 } 96 for(int i = 0;i < n;i++) 97 a[n-1][i] = 1; 98 x[n-1] = 1; 99 100 101 for(int k = 0;k < n-1;k++) 102 if(g[n-1][k] == 0) 103 { 104 for(int i = 0;i < n-1;i++) 105 { 106 if(g[n-1][i])a[i][var] = 1.0/(du[n-1]+1); 107 else a[i][var] = 0; 108 } 109 a[k][var] = 1.0/(du[n-1]+1); 110 a[n-1][var] = 1; 111 add[var] = k; 112 var++; 113 } 114 115 if(!Gauss()) 116 { 117 printf("INF\n"); 118 continue; 119 } 120 double tt = x[n-1]; 121 double now = x[n-1]; 122 int ans = -1; 123 for(int i = n;i < var;i++) 124 { 125 if(x[n-1]/a[n-1][i] > now) 126 { 127 ans = add[i]; 128 now = x[n-1]/a[n-1][i]; 129 } 130 } 131 printf("%d %d\n",1,ans); 132 } 133 return 0; 134 }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想