标签:
A. POJ 1679 The Unique MST
题意:最小生成树是不是唯一的。
思路:参考http://www.cnblogs.com/onlyAzha/p/4793031.html
B. HDU 4081 Qin Shi Huang‘s National Road System
题意:秦始皇想要在城市之间修路。徐福可以用法力帮助他修一条路。秦始皇希望修一条路使得剩下的路需要的花费B最少,而徐福希望这条路所连的两个城市的人口数之和A最大。权衡后他们决定选择A/B的值最大的边来修建。
思路:可以想到A/B的最大值必然是在最小生成树上,或者在最小生成树上加入一条边,然后删去形成的环中最长的那条边。用求次小生成树的方法,求出MAX[i][j],即i,j两点路径上A/B的最大值。然后再枚举每一条不在最小生成树上的边,加入这条边,然后删去路径上最长的边,求出最大的A/B。
#include<time.h> #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<math.h> #include<cctype> #define ll long long #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t)) #define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t)) #define PII pair<int,int> #define fst first #define snd second #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&(x)) #define RII(x,y) scanf("%d%d",&(x),&(y)) #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z)) #define DRI(x) int (x);scanf("%d",&(x)) #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y)) #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z)) #define RS(x) scanf("%s",x) #define RSS(x,y) scanf("%s%s",x,y) #define DRS(x) char x[maxn];scanf("%s",x) #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y) #define MS0(a) memset((a),0,sizeof((a))) #define MS1(a) memset((a),-1,sizeof((a))) #define MS(a,b) memset((a),(b),sizeof((a))) #define ALL(v) v.begin(),v.end() #define SZ(v) (int)(v).size() using namespace std; int T,n,m,w,flag; double ans; const int MAXN=1100; const double inf=1e14; struct v{ int x,y; }v[MAXN]; bool vis[MAXN]; double lowc[MAXN]; int pre[MAXN]; int po[MAXN]; double Max[MAXN][MAXN];//Max[i][j]表示在最小生成树中从i到j的路径中的最大边权 bool used[MAXN][MAXN]; double cost[MAXN][MAXN]; double a; double dist(int i,int j) { return sqrt((v[i].x-v[j].x)*(v[i].x-v[j].x)+(v[i].y-v[j].y)*(v[i].y-v[j].y)); } double Prim(double cost[][MAXN],int n) { double ans=0; memset(vis,false,sizeof(vis)); memset(Max,0,sizeof(Max)); memset(used,false,sizeof(used)); vis[0]=true; pre[0]=-1; for(int i=1;i<n;i++) { lowc[i]=cost[0][i]; pre[i]=0; } lowc[0]=0; for(int i=1;i<n;i++) { double minc=inf; int p=-1; for(int j=0;j<n;j++) if(!vis[j]&&minc>lowc[j]) { minc=lowc[j]; p=j; } if(p==-1)return -1; ans+=minc; vis[p]=true; used[p][pre[p]]=used[pre[p]][p]=true; for(int j=0;j<n;j++) { if(vis[j]&&j!=p) Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]); if(!vis[j]&&lowc[j]>cost[p][j]) { lowc[j]=cost[p][j]; pre[j]=p; } } } return ans; } int main() { //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { a=0; memset(v,0,sizeof(v)); memset(po,0,sizeof(po)); scanf("%d",&n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(i==j)cost[i][j]=0; else cost[i][j]=inf; } for(int i=0;i<n;i++) { scanf("%d%d%d",&v[i].x,&v[i].y,&po[i]); for(int j=0;j<i;j++) cost[i][j]=cost[j][i]=dist(i,j); } ans=Prim(cost,n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j) { if(!used[i][j]) a=max((po[i]+po[j])*1.0/(ans-Max[i][j]),a); else a=max((po[i]+po[j])*1.0/(ans-cost[i][j]),a); } printf("%.2f\n",a); } return 0; }
E. POJ 3164 Command Network
最小树形图。朱刘算法。
#include<time.h> #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<cmath> #include<cctype> #define ll long long #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t)) #define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t)) #define PII pair<int,int> #define fst first #define snd second #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&(x)) #define RII(x,y) scanf("%d%d",&(x),&(y)) #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z)) #define DRI(x) int (x);scanf("%d",&(x)) #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y)) #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z)) #define RS(x) scanf("%s",x) #define RSS(x,y) scanf("%s%s",x,y) #define DRS(x) char x[maxn];scanf("%s",x) #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y) #define MS0(a) memset((a),0,sizeof((a))) #define MS1(a) memset((a),-1,sizeof((a))) #define MS(a,b) memset((a),(b),sizeof((a))) #define ALL(v) v.begin(),v.end() #define SZ(v) (int)(v).size() using namespace std; const int INF=0x3f3f3f3f; const int MAXN=110; const int MAXM=40010; struct Edge{ int u,v; double cost; }; struct V{ int x,y; }vn[200]; Edge edge[MAXM]; int pre[MAXN],id[MAXN],visit[MAXN]; double in[MAXN]; double zhuliu(int root,int n,int m,Edge edge[]) { double res=0; int u,v; while(1) { for(int i=0;i<n;i++) in[i]=INF*1.0; for(int i=0;i<m;i++) if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].cost; } for(int i=0;i<n;i++) if(i!=root&&in[i]==INF*1.0) return -1; int tn=0; memset(id,-1,sizeof(id)); memset(visit,-1,sizeof(visit)); in[root]=0; for(int i=0;i<n;i++) { res+=in[i]; v=i; while(visit[v]!=i&&id[v]==-1&&v!=root) { visit[v]=i; v=pre[v]; } if(v!=root&&id[v]==-1) { for(int u=pre[v];u!=v;u=pre[u]) id[u]=tn; id[v]=tn++; } } if(tn==0) break; for(int i=0;i<n;i++) if(id[i]==-1) id[i]=tn++; for(int i=0;i<m;) { v=edge[i].v; edge[i].u=id[edge[i].u]; edge[i].v=id[edge[i].v]; if(edge[i].u!=edge[i].v) edge[i++].cost-=in[v]; else swap(edge[i],edge[--m]); } n=tn; root=id[root]; } return res; } double g[MAXN][MAXN]; double dist(int i,int j) { return sqrt((vn[i].x-vn[j].x)*(vn[i].x-vn[j].x)*1.0+(vn[i].y-vn[j].y)*(vn[i].y-vn[j].y)); } int main() { //freopen("in.txt","r",stdin); int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(vn,0,sizeof(vn)); memset(g,0,sizeof(g)); memset(edge,0,sizeof(edge)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) g[i][j]=INF; int u,v; double cost; for(int i=0;i<n;i++) scanf("%d%d",&vn[i].x,&vn[i].y); while(m--) { scanf("%d%d",&u,&v); u--,v--; if(u==v) continue; cost=dist(u,v); g[u][v]=min(g[u][v],cost); } int L=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(g[i][j]<INF) { edge[L].u=i; edge[L].v=j; edge[L++].cost=g[i][j]; } double ans=zhuliu(0,n,L,edge); if(ans==-1) printf("poor snoopy\n"); else printf("%.2lf\n",ans); } }
F. UVA 11183 Teen Girl Squad
#include<time.h> #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<math.h> #include<cctype> #define ll long long #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t)) #define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t)) #define PII pair<int,int> #define fst first #define snd second #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&(x)) #define RII(x,y) scanf("%d%d",&(x),&(y)) #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z)) #define DRI(x) int (x);scanf("%d",&(x)) #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y)) #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z)) #define RS(x) scanf("%s",x) #define RSS(x,y) scanf("%s%s",x,y) #define DRS(x) char x[maxn];scanf("%s",x) #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y) #define MS0(a) memset((a),0,sizeof((a))) #define MS1(a) memset((a),-1,sizeof((a))) #define MS(a,b) memset((a),(b),sizeof((a))) #define ALL(v) v.begin(),v.end() #define SZ(v) (int)(v).size() using namespace std; const int INF=0x3f3f3f3f; const int MAXN=1010; const int MAXM=40010; struct Edge{ int u,v,cost; }; Edge edge[MAXM]; int pre[MAXN],id[MAXN],visit[MAXN],in[MAXN]; int zhuliu(int root,int n,int m,Edge edge[]) { int res=0,u,v; while(1) { for(int i=0;i<n;i++) in[i]=INF; for(int i=0;i<m;i++) if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].cost; } for(int i=0;i<n;i++) if(i!=root&&in[i]==INF) return -1; int tn=0; memset(id,-1,sizeof(id)); memset(visit,-1,sizeof(visit)); in[root]=0; for(int i=0;i<n;i++) { res+=in[i]; v=i; while(visit[v]!=i&&id[v]==-1&&v!=root) { visit[v]=i; v=pre[v]; } if(v!=root&&id[v]==-1) { for(int u=pre[v];u!=v;u=pre[u]) id[u]=tn; id[v]=tn++; } } if(tn==0) break; for(int i=0;i<n;i++) if(id[i]==-1) id[i]=tn++; for(int i=0;i<m;) { v=edge[i].v; edge[i].u=id[edge[i].u]; edge[i].v=id[edge[i].v]; if(edge[i].u!=edge[i].v) edge[i++].cost-=in[v]; else swap(edge[i],edge[--m]); } n=tn; root=id[root]; } return res; } int g[MAXN][MAXN]; int main() { //freopen("in.txt","r",stdin); int n,m; int iCase=0; int T; scanf("%d",&T); while(T--) { iCase++; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) for(int j=0;j<n;j++) g[i][j]=INF; int u,v,cost; while(m--) { scanf("%d%d%d",&u,&v,&cost); if(u==v) continue; g[u][v]=min(g[u][v],cost); } int L=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(g[i][j]<INF) { edge[L].u=i; edge[L].v=j; edge[L++].cost=g[i][j]; } int ans=zhuliu(0,n,L,edge); printf("Case #%d: ",iCase); if(ans==-1) printf("Possums!\n"); else printf("%d\n",ans); } }
G. HDU 2121 Ice_cream‘s World II
#include<iostream> using namespace std; #include<cstdio> #include<cstring> #define MAXN 1005 #define INF 0x7f7f7f7f typedef __int64 type; struct node//边的权和顶点 { int u, v; type w; }edge[MAXN * MAXN]; int pre[MAXN], id[MAXN], vis[MAXN], n, m, pos; type in[MAXN];//存最小入边权,pre[v]为该边的起点 type Directed_MST(int root, int V, int E) { type ret = 0;//存最小树形图总权值 while(true) { int i; //1.找每个节点的最小入边 for( i = 0; i < V; i++) in[i] = INF;//初始化为无穷大 for( i = 0; i < E; i++)//遍历每条边 { int u = edge[i].u; int v = edge[i].v; if(edge[i].w < in[v] && u != v)//说明顶点v有条权值较小的入边 记录之 { pre[v] = u;//节点u指向v in[v] = edge[i].w;//最小入边 if(u == root)//这个点就是实际的起点 pos = i; } } for( i = 0; i < V; i++)//判断是否存在最小树形图 { if(i == root) continue; if(in[i] == INF) return -1;//除了根以外有点没有入边,则根无法到达它 说明它是独立的点 一定不能构成树形图 } //2.找环 int cnt = 0;//记录环数 memset(id, -1, sizeof(id)); memset(vis, -1, sizeof(vis)); in[root] = 0; for( i = 0; i < V; i++) //标记每个环 { ret += in[i];//记录权值 int v = i; while(vis[v] != i && id[v] == -1 && v != root) { vis[v] = i; v = pre[v]; } if(v != root && id[v] == -1) { for(int u = pre[v]; u != v; u = pre[u]) id[u] = cnt;//标记节点u为第几个环 id[v] = cnt++; } } if(cnt == 0) break; //无环 则break for( i = 0; i < V; i++) if(id[i] == -1) id[i] = cnt++; //3.建立新图 缩点,重新标记 for( i = 0; i < E; i++) { int u = edge[i].u; int v = edge[i].v; edge[i].u = id[u]; edge[i].v = id[v]; if(id[u] != id[v]) edge[i].w -= in[v]; } V = cnt; root = id[root]; } return ret; } int main() { int i; while(scanf("%d%d", &n, &m) != EOF) { type sum = 0; for( i = 0; i < m; i++) { scanf("%d%d%I64d", &edge[i].u, &edge[i].v, &edge[i].w); edge[i].u++; edge[i].v++; sum += edge[i].w; } sum ++; for( i = m; i < m + n; i++)//增加超级节点0,节点0到其余各个节点的边权相同(此题中 边权要大于原图的总边权值) { edge[i].u = 0; edge[i].v = i - m + 1; edge[i].w = sum; } type ans = Directed_MST(0, n + 1, m + n); //n+1为总结点数,m+n为总边数 //ans代表以超级节点0为根的最小树形图的总权值, //将ans减去sum,如果差值小于sum,说明节点0的出度只有1,说明原图是连通图 //如果差值>=sum,那么说明节点0的出度不止为1,说明原图不是连通图 if(ans == -1 || ans - sum >= sum) puts("impossible"); else printf("%I64d %d\n",ans - sum, pos - m); puts(""); } return 0; }
I. UVA 10766 Organising the Organisation
生成树计数模板
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=55; typedef long long LL; int D[N][N]; LL C[N][N];//Kirchhoff矩阵 LL Det(LL a[][N],int n)//生成树计数:Matrix-Tree定理 { LL ret=1; for(int i=1; i<n; i++) { for(int j=i+1; j<n; j++) while(a[j][i]) { LL t=a[i][i]/a[j][i]; for(int k=i; k<n; k++) a[i][k]=(a[i][k]-a[j][k]*t); for(int k=i; k<n; k++) swap(a[i][k],a[j][k]); ret=-ret; } if(a[i][i]==0) return 0; ret=ret*a[i][i]; } if(ret<0) ret=-ret; return ret; } int main() { //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); int n,m,k; while(~scanf("%d%d%d",&n,&m,&k)) { memset(C,0,sizeof(C)); memset(D,0,sizeof(D)); int u,v; while(m--) { scanf("%d%d",&u,&v); u--; v--; D[u][v]=D[v][u]=1; } for(int i=0; i<n; i++) { int u=0; for(int j=0; j<n; j++) { if(i!=j&&!D[i][j]) { u++; C[i][j]=-1; } } C[i][i]=u; } LL res=Det(C,n); printf("%lld\n",res); } return 0; }
L. HDU 4305 Lightning
#include<time.h> #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<math.h> #include<cctype> #define ll long long #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t)) #define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t)) #define PII pair<int,int> #define fst first #define snd second #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&(x)) #define RII(x,y) scanf("%d%d",&(x),&(y)) #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z)) #define DRI(x) int (x);scanf("%d",&(x)) #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y)) #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z)) #define RS(x) scanf("%s",x) #define RSS(x,y) scanf("%s%s",x,y) #define DRS(x) char x[maxn];scanf("%s",x) #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y) #define MS0(a) memset((a),0,sizeof((a))) #define MS1(a) memset((a),-1,sizeof((a))) #define MS(a,b) memset((a),(b),sizeof((a))) #define ALL(v) v.begin(),v.end() #define SZ(v) (int)(v).size() using namespace std; const int MOD=10007; const int MAXN=1000; const int MAXM=50000; const double eps=1e-18; struct Point{ int x,y; Point(int _x=0,int _y=0) { x=_x;y=_y; } Point operator - (const Point &b)const { return Point(x-b.x,y-b.y); } int operator ^ (const Point &b)const { return x*b.y-y*b.x; } void input() { scanf("%d%d",&x,&y); } }; struct Line{ Point s,e; Line(){} Line(Point _s,Point _e) { s=_s;e=_e; } }; ll g[MAXN][MAXN]; ll degree[MAXN]; ll a[MAXN][MAXN]; Point p[MAXN]; int T,n,m,u,v; int R; bool onSeg(Point P,Line L) { return ((L.s-P)^(L.e-P)) == 0 && (P.x-L.s.x)*(P.x-L.e.x)<=0 && (P.y-L.s.y)*(P.y-L.e.y)<=0; } int dist(Point a,Point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } bool check(int k1,int k2) { Line(p[k1],p[k2]); if(dist(p[k1],p[k2])<=R*R) { for(int i=0;i<n;i++) { if(i!=k1&&i!=k2) if(onSeg(p[i],Line(p[k1],p[k2]))) return 0; } return 1; } return 0; } int sgn(double x) { if(fabs(x)<eps) return 0; if(x<0) return -1; else return 1; } ll inv(ll a,ll b) { if(a==1) return 1; return inv(b%a,b)*(b-b/a)%b; } ll det(ll a[][MAXN],int n) { ll ret=1; int i,j,k; for(int i=0;i<n;i++) for(int j=0;j<n;j++) a[i][j]=(a[i][j]%MOD+MOD)%MOD; for(i=0;i<n;i++) { if(a[i][i]==0) { for(j=i+1;j<n;j++) if(a[j][i]) break; if(j==n) return -1; for(k=i;k<n;k++) swap(a[i][k],a[j][k]); ret=(-ret+MOD)%MOD; } ret=(ret*a[i][i])%MOD; ll tp=inv(a[i][i],MOD)%MOD; for(k=i+1;k<n;k++) a[i][k]=(a[i][k]*tp)%MOD; for(j=i+1;j<n;j++) for(k=i+1;k<n;k++) { a[j][k]=(a[j][k]-a[j][i]*a[i][k])%MOD; if(j==k) a[j][k]=(a[j][k]+MOD)%MOD; } } return ret; } int main() { //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { memset(degree,0,sizeof(degree)); memset(g,0,sizeof(g)); memset(a,0,sizeof(a)); memset(p,0,sizeof(p)); scanf("%d%d",&n,&R); for(int i=0;i<n;i++) p[i].input(); for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(check(i,j)) { degree[i]++; degree[j]++; g[j][i]=g[i][j]=1; } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(g[i][j]&&i!=j) a[i][j]=-1; a[i][i]=degree[i]; } ll ans=det(a,n-1); printf("%lld\n",ans); } return 0; }
N. SPOJ HIGH
#include<time.h> #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<math.h> #include<cctype> #define ll long long #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t)) #define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t)) #define PII pair<int,int> #define fst first #define snd second #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&(x)) #define RII(x,y) scanf("%d%d",&(x),&(y)) #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z)) #define DRI(x) int (x);scanf("%d",&(x)) #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y)) #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z)) #define RS(x) scanf("%s",x) #define RSS(x,y) scanf("%s%s",x,y) #define DRS(x) char x[maxn];scanf("%s",x) #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y) #define MS0(a) memset((a),0,sizeof((a))) #define MS1(a) memset((a),-1,sizeof((a))) #define MS(a,b) memset((a),(b),sizeof((a))) #define ALL(v) v.begin(),v.end() #define SZ(v) (int)(v).size() using namespace std; const int MAXN=100; const double eps=1e-18; double a[MAXN][MAXN]; int b[MAXN][MAXN]; int sgn(double x) { if(fabs(x)<eps) return 0; if(x<0) return -1; else return 1; } double det(double a[][MAXN],int n) { double ret=1; int sign=0,i,j,k; for(i=0;i<n;i++) { if(sgn(a[i][i])==0) { for(j=i+1;j<n;j++) if(sgn(a[j][i])) break; if(j==n) return 0; for(k=i;k<n;k++) swap(a[i][k],a[j][k]); sign++; } ret*=a[i][i]; for(k=i+1;k<n;k++) a[i][k]/=a[i][i]; for(j=i+1;j<n;j++) for(k=i+1;k<n;k++) a[j][k]-=a[j][i]*a[i][k]; } if(sign&1) ret=-ret; return ret; } int main() { //freopen("in.txt","r",stdin); int T,n,m,u,v; scanf("%d",&T); while(T--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&u,&v); u--,v--; b[u][v]=b[v][u]=1; } for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j&&b[i][j]) { a[i][i]++; a[i][j]=-1; } double ans=det(a,n-1); printf("%.0lf\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/onlyAzha/p/4802016.html